源码分析 — LauncherActivity(Launcher界面)

一、概述

在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);
    }
}

三、小结

  1. 在Launcher界面,通过PackageManager查询与给定的Intent相匹配的应用信息;
  2. 将返回的信息进行数据封装及转换;
  3. 将数据设置到ListView的Adapter(适配器)中;
  4. 当点击对应图标的时候,启动 Activity
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值