以拨号应用为例子分析应用的运行过程
当一个应用部署到模拟环境上后,系统就会读取这个应用的工程清单文件(AndroidManifest.xml),然后它就知道了,这个应用有哪些组件,然后登记这个应用中的组件。登记的信息包括:组件名和激活这个组件需要的信息(filter中的action,category和data)
组件名”sjtu.wade.dung_beetle.MainActivity”
动作名称”android.intent.action.MAIN”
类别”android.intent.category.LAUNCHER”
数据(后面会用到)
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="sjtu.wade.dung_beetle" android:versionCode="1" android:versionName="1.0" > <!--package 应用的包,四大组件必须在该包或其子包下创建 。用于设置应用程序的进程名,即在运行时使用ddms查看到的进程名。 android:versionCode应用的版本 android:versionName版本的名称 --> <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="19" /> <uses-permission android:name="android.permission.CALL_PHONE" android:maxSdkVersion="19"/> <!--android:icon应该的图标。@drawable/ic_launcher<==>R文件中,drawable这个内部类中,常量ic_launcher引用的资源 android:label应该的标题。当activity中不定义这个属性的时候,我们看到的应用的名字就是application中的这个属性的值,如果 activity中定义这个属性,应用的名字就是activity这个属性的值 android:versionName版本的名称 --> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <!--activty类似struts中action android:name=".MainActivity"(.表示当前应该所在的包,即manifest下package属性的值) android:label,指定每个activity的标题 <intent-filter>意图过滤器 --> <activity android:name="sjtu.wade.dung_beetle.MainActivity" android:label="@string/app_name" > <intent-filter> <!--"android.intent.action.MAIN"表示这个activity是这个应用的入口 "android.intent.category.LAUNCHER"类别,表示这个activity会出现在启动器里面 --> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
用户点击应用后,操作系统会把这个行为封装成一个意图(intent)。意图里面包含三个内容(filter中的action category和data)。然后传给操作系统中的意图处理器。意图处理器就回拿着这个信息去注册表中找与信息相匹配的组件。找到组件类后,会对组件类进行实例化(使用反射的方式实现实例化)。实例化完成后就调用这个组件类的onCreate方法(这个方法只会执行一次)。
注:如果匹配多个,系统会弹出选择框让你选择
public class MainActivity extends Activity { EditText et; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); et = (EditText)findViewById(R.id.editText_num); Button btn = (Button)findViewById(R.id.button); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // TODO Auto-generated method stub String mobile = et.getText().toString(); Intent intent = new Intent("android.intent.action.CALL",Uri.parse("tel:"+mobile)); startActivity(intent); //内部会添加android.intent.category.DEFAULT } }); } }
根据以上代码,执行完onCreate后启动监听button按钮的动作,当用户按下拨号按钮后,会向系统发出一个intent,里面同样包含三个内容(filter中的action category和data)。系统就会根据intent去找对应的打电话的组件,并实例化,执行对应的onCreate方法
根据android拨打电话组件的源码可知具体需要的内容为:
组件名”android.intent.action.CALL”
类别android.intent.category.DEFAULT
data:Uri.parse(“tel:”+mobile),scheme规定了data的格式
Intent intent = new Intent(“android.intent.action.CALL”,Uri.parse(“tel:”+mobile));
以上这条语句会把组件名和data放到intent中
startActivity(intent); 内部会添加android.intent.category.DEFAULT
结束。