Noodlecode parody of spaghetti code

Category: Notes (page 2 of 8)

ActionBarImplBase can only be used with a compatible window decor layout

ActionBarImplBase can only be used with a compatible window decor layout

This error occured in android 2.3 if you’re trying to use ActionBar feature on theme that disable ActionBar

Let’s say you define a style that enable actionbar overlay mode

<style name="MyTheme" parent="Theme.AppCompat">
     <item name="android:windowActionBarOverlay">true</item>
     <item name="windowActionBarOverlay">true</item>
</style>

Then one style extends this base style, but disable the actionbar

<style name="MyDifferentTheme" parent="MyTheme">
     <item name="android:windowActionBar">false</item>
     <item name="windowActionBar">false</item>
</style>

This will cause the crash. To fix it, the new style either need to extend different parent style, or disable the actionbar feature

<style name="MyDifferentTheme" parent="MyTheme">
     <item name="android:windowActionBar">false</item>
     <item name="windowActionBar">false</item>
     <item name="android:windowActionBarOverlay">false</item>
     <item name="windowActionBarOverlay">false</item>
</style>

JS parseBool()

This function cast any variable into type ‘boolean’

function parseBool(value) {
     return !!value;
}

console.log(typeof parseBool({}));
// “boolean"

Git download specific tag

git clone <repo_url>

# list out tags
git tag -l 

# checkout specific tag
git checkout tags/<tag_name>

Restart ADB

The most important script for an Android developer

cd /usr/local/bin
vim restart_adb

#!/bin/bash
adb kill-server
adb start-server

:wq
chmod +x restart_adb

iOS simulator folder

Up until iOS 7
~/Library/Application Support/iPhone Simulator/<ios version>

New in iOS 8
~/Library/Developer/CoreSimulator/Devices/<simulator id>

Add custom framework to Titanium iOS module

For example, I’m creating a module com.mymod, which include MillennialMedia SDK, that has 2 custom frameworks:

  • MillennialMedia.framework
  • SpeechKit.framework

Copy the frameworks into <module folder>/platform/iphone/custom_frameworks

Open the module in Xcode & include the framework – you can choose to include into any folder, for example the root of project

Edit module.xcconfig. Choose a unique variable name to set the environment variables (e.g MYMOD)

MYMOD_ID=com.mymod
MYMOD_VER=1.0
MYMOD_DIR=$(SRCROOT)/../../modules/iphone/$(COM_MYMOD_MYMOD_ID)/$(COM_MYMOD_MYMOD_VER)/platform/iphone

OTHER_LDFLAGS=$(inherited) -F"$(COM_MYMOD_MYMOD_DIR)/custom_frameworks" -framework MillennialMedia -F SpeechKit

Notice that we’re not using the defined env vars. This is because Titanium build script rename the var based on the module id (com.mymod becomes COM_MYMOD). If we’re referring to the var name that we define, it produces distorted value, example, MYMOD_VER become ” 1.0 1.0″

Reference: https://developer.appcelerator.com/question/132459/module-dev-third-party-framework

ScrollableView in ListView

Using ListView is all about mapping collection data structure to UI structure. What if we have a UI structure that have nested collection in a single ListItem, such as a ScrollableView? We have to make sure our data structure can map to the ScrollableView.views property.

News (data) Ti.UI
previews[] ScrollableView.views
title Label.text
timestamp Label.text

The solution: we have to create each child view when setting items to ListView. Here’s how:

var win = Ti.UI.createWindow({
    exitOnClose: true,
    title: 'ScrollableView in ListView'
});

var newsTemplate = {
    childTemplates: [
        {
            type: 'Ti.UI.View',
            properties: {
                width: 300,
                backgroundColor: '#fff',
                borderColor: '#ccc',
                layout: 'vertical',
                top: 10
            },
            childTemplates: [
                {
                    type: 'Ti.UI.ScrollableView',
                    bindId: 'previews',
                    properties: {
                        width: 300,
                        height: 150
                    }
                },
                {
                    type: 'Ti.UI.Label',
                    bindId: 'title',
                    properties: {
                        color: '#333',
                        width: Ti.UI.FILL,
                        textAlign: Ti.UI.TEXT_ALIGNMENT_LEFT,
                        left: 5,
                        right: 5,
                        wordWrap: false,
                        ellipsize: true,
                        font: {
                            fontSize: '14dp',
                            fontWeight: 'bold'
                        }
                    }
                },
                {
                    type: 'Ti.UI.Label',
                    bindId: 'published',
                    properties: {
                        color: '#aaa',
                        width: Ti.UI.FILL,
                        textAlign: Ti.UI.TEXT_ALIGNMENT_LEFT,
                        left: 5,
                        right: 5,
                        wordWrap: false,
                        ellipsize: true,
                        font: {
                            fontSize: '12dp'
                        }
                    }
                }
            ]
        }
    ]
};

var sect = Ti.UI.createListSection();

var listView = Ti.UI.createListView({
    templates: {
        news: newsTemplate,
        foot: {
            properties: {
                height: 10
            }
        }
    },
    backgroundColor: '#eee',
    separatorColor: '#eee',
    sections: [sect]
});
win.add(listView);

var data = [
    {
        title: 'News A',
        timestamp: 1411789472624,
        previews: [
            'http://placehold.it/300x150/0099cc/ffffff',
            'http://placehold.it/300x150/9933cc/ffffff',
            'http://placehold.it/300x150/669900/ffffff',
            'http://placehold.it/300x150/ff8800/ffffff'
        ]
    },
    {
        title: 'News B',
        timestamp: 1411443872624,
        previews: [
            'http://placehold.it/300x150/cc0000/ffffff',
            'http://placehold.it/300x150/33b5e5/ffffff',
            'http://placehold.it/300x150/aa66cc/ffffff'
        ]
    },
    {
        title: 'News C',
        timestamp: 1411184672624,
        previews: [
            'http://placehold.it/300x150/99cc00/ffffff',
            'http://placehold.it/300x150/ffbb33/ffffff',
            'http://placehold.it/300x150/ff4444/ffffff',
            'http://placehold.it/300x150/0099cc/ffffff',
            'http://placehold.it/300x150/9933cc/ffffff',
        ]
    }
];

win.addEventListener('open', function() {
    var items = [];

    var getDate = function(timestamp) {
        var d = new Date(timestamp);
        var m = d.getMonth() + 1;
        if (m > 12) {
            m = 1;
        }
        return d.getDate() +'/'+ m +'/'+ d.getFullYear();
    };

    for (var i = 0; i < data.length; i++) {
        var d = data[i];

        var views = [];
        for (var j = 0; j < d.previews.length; j++) {
            views.push(Ti.UI.createImageView({
                image: d.previews[j],
                width: 300,
                height: 150
            }));
        }

        items.push({
            template: 'news',
            previews: {
                views: views
            },
            title: {
                text: d.title
            },
            published: {
                text: 'Published on '+ getDate(d.timestamp)
            }
        });
    }

    items.push({
        template: 'foot'
    });

    sect.setItems(items);
});

win.open();

Output:
scrollableview-in-listview

Titanium Studio unbound classpath container error

Faced this error while creating Titanium module. This solution is not in exact order, however after trying all the steps I finally could get rid of the error message

Environment:

Set JAVA_HOME

  • edit ~/.bash_profile
  • export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
  • source ~/.bash_profile

Edit Titanium Studio preferences

  • Preferences > Java > Compiler
  • set ‘Compiler compliance level’ to ‘1.6’
  • Java > Installed JREs > Add > Standard VM
  • set ‘JRE Home’ to JAVA_HOME
  • Finish
  • clean project

After cleaning the project, the error should go away

session_regenerate_id() old data not copied to new session ID

In PHP I’m using MySQL with Memcached backend for storing session information. Every few minutes I need to regenerate the session ID to prevent replay attack. However when using session_regenerate_id(true), sometimes session data from old ID are not copied to the new regenerated ID. Therefore everytime when the session regenerated, I’ll be logged out if I’m currently logged in to the web app.

To fix it, I need to regenerate the ID without deleting the old data, flush the session data into database, stop then restart the session with new ID

session_regenerate_id();
$new_sess_id = session_id();

// this enable the backend to write the session data to backend storage
$this->data_changed = true; 

// this will call the write() function to save session data to backend
session_write_close(); 

session_id($new_sess_id);
session_start();

Using database in Windows Phone app

Database in windows phone app is using LINQ to SQL, a .NET component that provide infrastructure for managing relational data as objects (reference). Creating and manipulating the database require a few steps from defining the data structure to querying the database

For this example, we have a database named School with one table Student

Student
- id <int> (PK)
- name <string>
- biography <string>
- registered <datetime>
- major <StudentMajor>

StudentMajor (enumerable)
- Engineering
- Medical
- Computer Science

First, define the table and enum class above. ‘ID’ is primary key, autoincrement field. ‘Biography’ field wont be checked for consistency when doing update operation. ‘Major’ contains enumerable value

[Table]
public class Student
{
    private int id;
    [Column(IsPrimaryKey = true, IsDbGenerated = true, DbType = "INT NOT NULL Identity", CanBeNull = false, AutoSync = AutoSync.OnInsert)]
    public int ID
    {
        get { return id; }
        set { id = value; }
    }

    private string name;
    [Column(DbType = "NVARCHAR(255)")]
    public string Name
    {
        get { return name; }
        set { name = value; }
    }

    private string biography;
    [Column(DbType = "NText", UpdateCheck=UpdateCheck.Never)]
    public string Biography
    {
        get { return biography; }
        set { biography = value; }
    }

    private DateTime registered;
    [Column]
    public DateTime Registered
    {
        get { return registered; }
        set { registered = value; }
    }

    private StudentMajor major;
    [Column]
    public StudentMajor Major
    {
        get { return major; }
        set { major = value; }
    }
}

public enum StudentMajor
{
    Engineering,
    Medical,
    ComputerScience
}

Next, define a database by extending DataContext class and override its base constructor

public class SchoolContext : DataContext
{
    public static string ConnectionString = "Data Source=isostore:/School.sdf";
    public Table<Student> Students;
    public SchoolContext(string connectionString) : base(connectionString) { }
}

Now, we can open the database and do some query on it.

SchoolContext db = new SchoolContext(SchoolContext.ConnectionString);

To query for student with ID 100

var result = from Student s in db.Students
             where s.ID == 100
             select s;
Student student = result.FirstOrDefault(); // return null if not found

To query for students enroll in Engineering major

var result = from Student s in db.Students
             where s.Major == StudentMajor.Engineering
             select s;
Student[] students = result.ToArray();

Note: for insert, update or delete operation, you need to call SubmitChanges() to save the changes to the database. Also note that you need to wrap SubmitChanges() in try catch block, to catch any possible error raised when saving the changes.

To insert new student record. (reference)

db.Students.InsertOnSubmit(new Student()
{
    Name = "John Doe",
    Biography = "Description about this student",
    Registered = DateTime.UtcNow,
    Major = StudentMajor.Medical
});
db.SubmitChanges();

To update a student record (reference)

var result = from Student s in db.Students
             where s.ID == 100
             select s;
Student student = result.FirstOrDefault();
if (student != null)
{
    student.Name = "James Bond";
    db.SubmitChanges();
}

To delete a student record (reference), for example student with ID 90

var result = from Student s in db.Students
             where s.ID == 100
             select s;
Student student = result.FirstOrDefault();
if (student != null)
{
    db.Students.DeleteOnSubmit(student);
    db.SubmitChanges();
}

To delete bulk record of students, for example student enrolled in ComputerScience major

var result = from Student s in db.Students
             where s.Major == StudentMajor.ComputerScience
             select s;
db.Students.DeleteAllOnSubmit(result.ToList());
db.SubmitChanges();
Older posts Newer posts

Copyright © 2017 Noodlecode