一、概述
在Launcher界面,我们会点击应用图标来启动对应的应用,那它又是在哪个类实现的呢?
分析:
一般手机的Launcher界面,界面的效果和我们平时所做的需求大同小异,无非就是Item展开显示;
源码版本: Android 23
二、源码分析
2.1 类 ListActivity
在介绍LaucherActivity之前,先来简单的看一下 ListActivity
;
/*
* ListActivity其实就是集成了一个默认的ListView;
*/
public class ListActivity extends Activity {
protected ListAdapter mAdapter;
protected ListView mList;
// ...
@Override
public void onContentChanged() {
super.onContentChanged();
// ...
mList.setOnItemClickListener(mOnClickListener);
// ...
}
/**
* Provide the cursor for the list view.
*/
public void setListAdapter(ListAdapter adapter) {
synchronized (this) {
mAdapter = adapter;
mList.setAdapter(adapter);
}
}
private AdapterView.OnItemClickListener mOnClickListener = new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
onListItemClick((ListView)parent, v, position, id);
}
};
/**
* 点击事件的回调:子类实现该方法即能接收点击事件的触发
*/
protected void onListItemClick(ListView l, View v, int position, long id) {
}
}
2.2 类 LauncherActivity
虽然 LauncherActivity
是个抽象类,但每个手机的 Launcher 界面都要继承它来实现功能;
public abstract class LauncherActivity extends ListActivity {
Intent mIntent;
PackageManager mPackageManager;
/**
* 这个实体对象就是Launcher上的一个Item
*/
public static class ListItem {
public ResolveInfo resolveInfo;//
public CharSequence label; //应用名
public Drawable icon; //应用图标
public String packageName; //启动的包名
public String className; //启动的Class名
public Bundle extras; //携带的数据
// ...
}
/**
* Adapter which shows the set of activities that can be performed for a given intent.
*/
private class ActivityAdapter extends BaseAdapter implements Filterable {
// ...
protected List<ListItem> mActivitiesList;
public ActivityAdapter(IconResizer resizer) {
mActivitiesList = makeListItems();
}
// 将对于Item中的信息组装成一个Intent,然后返回;
public Intent intentForPosition(int position) {
// 这里就是向Intent添加信息
Intent intent = new Intent(mIntent);
ListItem item = mActivitiesList.get(position);
intent.setClassName(item.packageName, item.className);
if (item.extras != null) {
intent.putExtras(item.extras);
}
return intent;
}
// ...
}
// 很熟悉的Activity的生命周期;
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(com.android.internal.R.layout.activity_list);
mPackageManager = getPackageManager();
// ...
mAdapter = new ActivityAdapter(mIconResizer);
setListAdapter(mAdapter);
// ...
}
// 这里触发了ListView的点击事件
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
Intent intent = adapter.intentForPosition(position);
startActivity(intent);
}
/**
* 对从PackageManager中查询出来的数据进行封装,转换成我们所需的ListItem数据结构;
*/
public List<ListItem> makeListItems() {
// Load all matching activities
List<ResolveInfo> list = onQueryPackageManager(mIntent);
// 下面部分是对查询出来的应用数据集合进行简单的封装;
ArrayList<ListItem> result = new ArrayList<ListItem>(list.size());
int listSize = list.size();
for (int i = 0; i < listSize; i++) {
ResolveInfo resolveInfo = list.get(i);
result.add(new ListItem(mPackageManager, resolveInfo, null));
}
return result;
}
/**
* 这个方法才是核心:通过PackageManager来查询指定Intent的应用集合;
* PackageManager的实现类是ApplicationPackageManager;
*/
protected List<ResolveInfo> onQueryPackageManager(Intent queryIntent) {
return mPackageManager.queryIntentActivities(queryIntent, /* no flags */ 0);
}
}
三、小结
- 在Launcher界面,通过PackageManager查询与给定的Intent相匹配的应用信息;
- 将返回的信息进行数据封装及转换;
- 将数据设置到ListView的Adapter(适配器)中;
- 当点击对应图标的时候,启动
Activity
;