2010년 3월 21일 일요일

[Android] Memory Analyzing

In order to get information about the memory usage on Android.
There are 2 useful command lines (you can invoke these command in adb shell).

1. adb shell procrank

2. adb shell dumpsys meminfo

For more detailed debugging for memory leakage, use eclipse MAT (Memory Analyzer)
About using MAT for an android app, have a look at the following blog.

http://kohlerm.blogspot.com/

2010년 3월 16일 화요일

[Android] Add hdpi to the build

In order to support hdpi in the device, you have to add hdpi to the makefile.

For example, in order to build a simulator that supports hdpi,

Edit generic.mk (under build/target/product).
Add the following lines at the end of the file.

PRODUCT_LOCALES := hdpi ...

You can add other configuration options like ko_KR en_US mdpi ldpi

2010년 3월 15일 월요일

[Android] Set Default Activity (Now investigating to find a way to set a default activity especially for Home)

Here is what I have found during the investigation.

Check is Preferred Activity is set (InstalledAppDetails.java)
------------------------
// Get list of preferred activities
mActivitiesButton = (Button)findViewById(R.id.clear_activities_button);
List prefActList = new ArrayList();
// Intent list cannot be null. so pass empty list
List intentList = new ArrayList();
mPm.getPreferredActivities(intentList, prefActList, packageName);
if(localLOGV) Log.i(TAG, "Have "+prefActList.size()+" number of activities in prefered list");
TextView autoLaunchView = (TextView)findViewById(R.id.auto_launch);
if(prefActList.size() <= 0) {
// Disable clear activities button
autoLaunchView.setText(R.string.auto_launch_disable_text);
mActivitiesButton.setEnabled(false);
} else {
autoLaunchView.setText(R.string.auto_launch_enable_text);
mActivitiesButton.setOnClickListener(this);
}

getPreferredActivities() will return not-zero number for the packageName.
If 'preActList" > 0, it is preferred activity set.


Clear the Preferred (or Default) Activity (InstalledAppDetails.java)
-------------------------------
} else if(v == mActivitiesButton) {
mPm.clearPackagePreferredActivities(packageName);
mActivitiesButton.setEnabled(false);


Set the Preferred Activity
-------------------------------
ResolveInfo ri = mAdapter.resolveInfoForPosition(which);
Intent intent = mAdapter.intentForPosition(which);

if ((mAlwaysCheck != null) && mAlwaysCheck.isChecked()) {
// Build a reasonable intent filter, based on what matched.
IntentFilter filter = new IntentFilter();

if (intent.getAction() != null) {
filter.addAction(intent.getAction());
}
Set categories = intent.getCategories();
if (categories != null) {
for (String cat : categories) {
filter.addCategory(cat);
}
}
filter.addCategory(Intent.CATEGORY_DEFAULT);

int cat = ri.match&IntentFilter.MATCH_CATEGORY_MASK;
Uri data = intent.getData();
if (cat == IntentFilter.MATCH_CATEGORY_TYPE) {
String mimeType = intent.resolveType(this);
if (mimeType != null) {
try {
filter.addDataType(mimeType);
} catch (IntentFilter.MalformedMimeTypeException e) {
Log.w("ResolverActivity", e);
filter = null;
}
}
} else if (data != null && data.getScheme() != null) {
filter.addDataScheme(data.getScheme());

// Look through the resolved filter to determine which part
// of it matched the original Intent.
Iterator aIt = ri.filter.authoritiesIterator();
if (aIt != null) {
while (aIt.hasNext()) {
IntentFilter.AuthorityEntry a = aIt.next();
if (a.match(data) >= 0) {
int port = a.getPort();
filter.addDataAuthority(a.getHost(),
port >= 0 ? Integer.toString(port) : null);
break;
}
}
}
Iterator pIt = ri.filter.pathsIterator();
if (pIt != null) {
String path = data.getPath();
while (path != null && pIt.hasNext()) {
PatternMatcher p = pIt.next();
if (p.match(path)) {
filter.addDataPath(p.getPath(), p.getType());
break;
}
}
}
}

if (filter != null) {
final int N = mAdapter.mList.size();
ComponentName[] set = new ComponentName[N];
int bestMatch = 0;
for (int i=0; i ResolveInfo r = mAdapter.mList.get(i).ri;
set[i] = new ComponentName(r.activityInfo.packageName,
r.activityInfo.name);
if (r.match > bestMatch) bestMatch = r.match;
}
getPackageManager().addPreferredActivity(filter, bestMatch, set,
intent.getComponent());
}
}


There is no way to set a preferred Home on the first boot up of the device.
I am considering 2 methods to do that.
1) Modify startHomeActivity() API in ActivityManagerService.java
2) Add a persistent Service and set preferred home on boot up. (This could be possible. Because all persistent services start before Home activity)