Android 源码分析(八) Launcher 桌面启动App过程
一.前言:
init进程 –> Zygote进程 –> SystemServer进程 –> Launcher桌面程序 -> 我们的App应用
init进程:linux的根进程,android系统是基于linux系统的,因此可以算作是整个android操作系统的第一个进程;
Zygote进程:android系统的根进程,主要作用:可以作用Zygote进程fork出SystemServer进程和各种应用进程;
SystemService进程:主要是在这个进程中启动系统的各项服务,比如ActivityManagerService,PackageManagerService,WindowManagerService服务等等;
Launcher桌面程序:就是我们平时看到的桌面程序,它其实也是一个android应用程序,只不过这个应用程序是系统默认第一个启动的应用程序.
二. Launcher 桌面启动App过程分析
Launcher应用程序在启动过程中会通过PackageManagerService服务请求查询系统所有的已安装应用的包名,图标和应用名称等信息,然后填充到Launcher中的Adapter中.
这样点击某一项应用图标的时候就可以根据该图标的包名和启动Activity的类名初始化Intent对象,然后调用startActivity(Intent)启动相关的应用程序了。
其实android中应用进程可以通过许多方式启动,比如启动一个Activity,启动一个Service,启动一个ContentProvider或者是一个BroadcastReceiver,也就是说我们可以通过启动四大组件的方式启动应用进程,在应用进程没有启动的时候,如果我们通过启动这些组件,这时候系统会判断当前这些组件所需要的应用进程是否已经启动,若没有的话,则会启动应用进程。
//LauncherActivity.java public abstract class LauncherActivity extends ListActivity { ...... @Override protected void onListItemClick(ListView l, View v, int position, long id) { Intent intent = intentForPosition(position); startActivity(intent); } ...... @Override public void startActivity(Intent intent) { this.startActivity(intent, null); } ...... @Override public void startActivity(Intent intent, @Nullable Bundle options) { if (options != null) { startActivityForResult(intent, -1, options); } else { // Note we want to go through this call for compatibility with // applications that may have overridden the method. startActivityForResult(intent, -1); } } ...... /** * Adapter which shows the set of activities that can be performed for a given intent. */ private class ActivityAdapter extends BaseAdapter implements Filterable { ...... public View getView(int position, View convertView, ViewGroup parent) { View view; if (convertView == null) { view = mInflater.inflate( com.android.internal.R.layout.activity_list_item_2, parent, false); } else { view = convertView; } bindView(view, mActivitiesList.get(position)); return view; } private void bindView(View view, ListItem item) { TextView text = (TextView) view; text.setText(item.label); if (mShowIcons) { if (item.icon == null) { item.icon = mIconResizer.createIconThumbnail(item.resolveInfo.loadIcon(getPackageManager())); } text.setCompoundDrawablesWithIntrinsicBounds(item.icon, null, null, null); } } ...... } }
//activity_list.xml Launcher 桌面就是一个列表控件,来存放所有应用的图标和名称 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <ListView android:id="@android:id/list" android:layout_width="match_parent" android:layout_height="match_parent" /> <TextView android:id="@android:id/empty" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:text="@string/activity_list_empty" android:visibility="gone" android:textAppearance="?android:attr/textAppearanceMedium" /> </FrameLayout>
//activity_list_item_2.xml 列表控件的子项,存放应用名称和应用logo。drawablePadding="14dip". <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:minHeight="?attr/listPreferredItemHeight" android:textAppearance="?attr/textAppearanceListItemSmall" android:gravity="center_vertical" android:drawablePadding="14dip" android:paddingStart="?attr/listPreferredItemPaddingStart" android:paddingEnd="?attr/listPreferredItemPaddingEnd" />
后面就进入了Activity的启动流程了。