2011.8.19(android中launcher启动过程中对widget做的一些操作)

来源:互联网 发布:用友协同软件 编辑:程序博客网 时间:2024/06/04 08:54

毫无疑问,launcher和widget有着先天的粘连关系,很简单,widget要显示在launcher中,widget的事件响应由launcher来控制。因此如果要理解widget,必须从launcher入手。下面就从代码级别来分析。

直接进入launcher的onCreate()方法:

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mInflater = getLayoutInflater();

        mAppWidgetManager = AppWidgetManager.getInstance(this);

        mAppWidgetHost = new LauncherAppWidgetHost(this, APPWIDGET_HOST_ID);
        mAppWidgetHost.startListening();

===================================================================================

初始化了一个LauncherAppWidgetHost,然后调用startListening()方法。

 

    /**
     * Start receiving onAppWidgetChanged calls for your AppWidgets.  Call this when your activity
     * becomes visible, i.e. from onStart() in your Activity.
     */

它的注释是开始接收onAppWidgetChanged 的调用,具体是怎么接收的呢,不是很了解

public void startListening() {
        int[] updatedIds;
        ArrayList<RemoteViews> updatedViews = new ArrayList<RemoteViews>();
       
        try {
            if (mPackageName == null) {
                mPackageName = mContext.getPackageName();
            }
            updatedIds = sService.startListening(mCallbacks, mPackageName, mHostId, updatedViews);
        }
        catch (RemoteException e) {
            throw new RuntimeException("system server dead?", e);
        }

        final int N = updatedIds.length;
        for (int i=0; i<N; i++) {
            updateAppWidgetView(updatedIds[i], updatedViews.get(i));
        }
    }

首先来看sService.startListening(mCallbacks, mPackageName, mHostId, updatedViews);
也就是AppWidgetService的startListening方法,代码如下:

   public int[] startListening(IAppWidgetHost callbacks, String packageName, int hostId,
            List<RemoteViews> updatedViews) {
        int callingUid = enforceCallingUid(packageName);
        synchronized (mAppWidgetIds) {
            Host host = lookupOrAddHostLocked(callingUid, packageName, hostId);
            host.callbacks = callbacks;

            updatedViews.clear();

            ArrayList<AppWidgetId> instances = host.instances;
            int N = instances.size();
            int[] updatedIds = new int[N];
            for (int i=0; i<N; i++) {
                AppWidgetId id = instances.get(i);
                updatedIds[i] = id.appWidgetId;
                updatedViews.add(id.views);
            }
            return updatedIds;
        }
    }

这个方法里packageName指的是launcher的packagename,hostId也是指为launcher分配的hostid,updatedViews是一个RemoteViews的数组。注意:这里传进去的第一个参数callbacks非常重要,顾名思义,是回调的作用,也就是AppWidgetService在未来的某个时候要调用callbacks的方法。我们再来AppWidgetHost里面看下callbacks的实现:

   class Callbacks extends IAppWidgetHost.Stub {
        public void updateAppWidget(int appWidgetId, RemoteViews views) {
            Message msg = mHandler.obtainMessage(HANDLE_UPDATE);
            msg.arg1 = appWidgetId;
            msg.obj = views;
            msg.sendToTarget();
        }

        public void providerChanged(int appWidgetId, AppWidgetProviderInfo info) {
            Message msg = mHandler.obtainMessage(HANDLE_PROVIDER_CHANGED);
            msg.arg1 = appWidgetId;
            msg.obj = info;
            msg.sendToTarget();
        }
    }

 

这个方法的作用就是找到与这个host相关的所有的appwidget并返回其id数组,其中host.instances的初始化是在readStateFromFileLocked方法中已经进行过了(框架在初始化时已经调用了这个方法)。

接下来就是LauncherAppWidgetHost里面继续调用updateAppWidgetView方法。由于目前是在启动launcher,所以此时这个方法其实什么也没有做。

到此,launcher的启动过程中widget的初始化已经结束。

 

至于如何添加widget到launcher桌面这个流程的代码分析下次再接着进行.....

 

 

 

 

 

原创粉丝点击