Activity
Android 中,Activity 是所有程序的根本,所有程序的流程都运行在Activity 之中,Activity 具有自己的生命周期(见 http://blog.csdn.net/teasub/archive/2011/03/15/6251974.aspx ,由系统控制生命周期,程序无法改变,但可以用onSaveInstanceState 保存其状态)。
对于Activity ,关键是其生命周期 的把握(如下图),其次就是状态的保存和恢复(onSaveInstanceState onRestoreInstanceState ),以及Activity 之间的跳转和数据传输(intent )。
Activity 中常用的函数有SetContentView() findViewById() finish() startActivity() , 其生命周期涉及的函数有:
void onCreate(Bundle savedInstanceState )
void onStart()
void onRestart()
void onResume()
void onPause()
void onStop()
void onDestroy()
注意的是,Activity 的使用需要在Manifest 文件中添加相应的<Activity> ,并设置其属性和intent-filter 。
Intent
Android 中提供了Intent 机制来协助应用间的交互与通讯,Intent 负责对应用中一次操作的动作、动作涉及数据、附加数据进行描述,Android 则根据此 Intent 的描述,负责找到对应的组件,将 Intent 传递给调用的组件,并完成组件的调用。Intent 不仅可用于应用程序之间,也可用于应用程序内部的Activity/Service 之间的 交互。因此,Intent 在这里起着一个媒体中介的作用,专门提供组件互相调用的相关信息,实现调用者与被调用者之间的解耦。在SDK 中给出了 Intent 作用的表现形式为:
Intent 属性的设置 ,包括以下几点:(以下为XML 中定义,当然也可以通过Intent 类的方法来获取和设置)
(1 )Action ,也就是要执行的动作
SDk 中定义了一些标准的动作,包括
onstant |
Target component |
Action |
ACTION_CALL |
activity |
Initiate a phone call. |
ACTION_EDIT |
activity |
Display data for the user to edit. |
ACTION_MAIN |
activity |
Start up as the initial activity of a task, with no data input and no returned output. |
ACTION_SYNC |
activity |
Synchronize data on a server with data on the mobile device. |
ACTION_BATTERY_LOW |
broadcast receiver |
A warning that the battery is low. |
ACTION_HEADSET_PLUG |
broadcast receiver |
A headset has been plugged into the device, or unplugged from it. |
ACTION_SCREEN_ON |
broadcast receiver |
The screen has been turned on. |
ACTION_TIMEZONE_CHANGED |
broadcast receiver |
The setting for the time zone has changed. |
当然,也可以自定义动作(自定义的动作在使用时,需要加上包名作为前缀,如" com.example.project.SHOW_COLOR ” ),并可定义相应的Activity 来处理我们的自定义动作。
(2 )Data ,也就是执行动作要操作的数据
Android 中采用指向数据的一个URI 来表示,如在联系人应用中,一个指向某联系人的URI 可能为:content://contacts/1 。对于不同的动作,其 URI 数据的类型是不同的(可以设置type 属性指定特定类型数据),如ACTION_EDIT 指定Data 为文件URI ,打电话为tel:URI ,访问 网络为http:URI ,而由content provider 提供的数据则为 content: URIs 。
(3 )type (数据类型),显式指定Intent 的数据类型(MIME )。一般Intent 的数据类型能够根据数据本身进行判定,但是通过设置这个属性,可以强制采用显式指定的类型而不再进行推导。
(4 )category (类 别),被执行动作的附加信息。例如 LAUNCHER_CATEGORY 表示Intent 的接受者应该在Launcher 中作为顶级应用出现;而ALTERNATIVE_CATEGORY 表示当前的Intent 是一系列的可选动作中的一个,这 些动作可以在同一块数据上执行。还有其他的为
Constant |
Meaning |
CATEGORY_BROWSABLE |
The target activity can be safely invoked by the browser to display data referenced by a link — for example, an image or an e-mail message. |
CATEGORY_GADGET |
The activity can be embedded inside of another activity that hosts gadgets. |
CATEGORY_HOME |
The activity displays the home screen, the first screen the user sees when the device is turned on or when the HOME key is pressed. |
CATEGORY_LAUNCHER |
The activity can be the initial activity of a task and is listed in the top-level application launcher. |
CATEGORY_PREFERENCE |
The target activity is a preference panel. |
( 5 ) component (组 件),指定 Intent 的的目标组件的类名称。通常 Android 会根据 Intent 中包含的其它属性的信息,比如 action 、 data/type 、 category 进行查找,最终找到一个与之匹配的目标组件。但是,如果 component 这个属性有指定的话,将直接使用它指定的组件,而不再执行上述查找过程。指定了这个属性以后, Intent 的其它所有属性都是可选的。
( 6 ) extras (附加信息),是其它所有附加信息的集合。使用 extras 可以为组件提供扩展信息,比如,如果要执行 “ 发送电子邮件 ” 这个动作,可以将电子邮件的标题、正文等保存在 extras 里,传给电子邮件发送组件。
理解 Intent 的关键之一是理解清楚 Intent 的两种基本用法:一种是 显式的 Intent ,即在构造 Intent 对象时就指定接收者;另一种是 隐式的 Intent ,即 Intent 的发送者在构造 Intent 对象时,并不知道也不关心接收者是谁,有利于降低发送者和接收者之间的耦合。
对 于显式 Intent , Android 不需要去做解析,因为目标组件已经很明确, Android 需要解析的是那些隐式 Intent ,通过解析,将 Intent 映射给可以处理此 Intent 的 Activity 、 IntentReceiver 或 Service 。
Intent 解析机制主要是通过查找已注册在 AndroidManifest.xml 中的所有 IntentFilter 及其中定义的 Intent ,最终找到匹配的 Intent 。在这个解析过程中, Android 是通过 Intent 的 action 、 type 、 category 这三个属性来进行判断的,判断方法如下:
Intent-Filter 的定义
一些属性设置的例子:
<action android:name="com.example.project.SHOW_CURRENT" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="video/mpeg" android:scheme="http" . . . />
<data android:mimeType="image/*" />
<data android:scheme="http" android:type="video/*" />
完整的实例
<activity android:name = "NotesList" android:label = "@string/title_notes_list" >
<intent-filter>
<action android:name = "android.intent.action.MAIN" />
<category android:name = "android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name = "android.intent.action.VIEW" />
<action android:name = "android.intent.action.EDIT" />
<action android:name = "android.intent.action.PICK" />
<category android:name = "android.intent.category.DEFAULT" />
<data android:mimeType = "vnd.android.cursor.dir/vnd.google.note" />
</intent-filter>
<intent-filter>
<action android:name = "android.intent.action.GET_CONTENT" />
<category android:name = "android.intent.category.DEFAULT" />
<data android:mimeType = "vnd.android.cursor.item/vnd.google.note" />
</intent-filter>
</activity>
Intent 用法实例
1. 无参数 Activity 跳转
Intent it = new Intent(Activity.Main. this , Activity2. class );
startActivity(it);
2. 向下一个 Activity 传递数据(使用 Bundle 和 Intent.putExtras )
Intent it = new Intent(Activity.Main. this , Activity2. class );
Bundle bundle= new Bundle();
bundle.putString(" name ", " This is from MainActivity! ");
it.putExtras(bundle); // it.putExtra(“test”, "shuju”);
startActivity(it); // startActivityForResult(it,REQUEST_CODE);
对于数据的获取可以采用:
Bundle bundle=getIntent().getExtras();
String name=bundle.getString(" name ");
3. 向上一个 Activity 返回结果(使用 setResult ,针对 startActivityForResult(it,REQUEST_CODE) 启动的 Activity )
Intent intent=getIntent();
Bundle bundle2= new Bundle();
bundle2.putString(" name ", " This is from ShowMsg! ");
intent.putExtras(bundle2);
setResult(RESULT_OK, intent);
4. 回调上一个 Activity 的结果处理函数( onActivityResult )
@Override
protected void onActivityResult( int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super .onActivityResult(requestCode, resultCode, data);
if (requestCode==REQUEST_CODE){
if (resultCode==RESULT_CANCELED)
setTitle(" cancle ");
else if (resultCode==RESULT_OK) {
String temp= null ;
Bundle bundle=data.getExtras();
if (bundle!= null ) temp=bundle.getString(" name ");
setTitle(temp);
}
}
}
下面是转载来的其他的一些 Intent 用法实例(转自 javaeye )
显示网页
1. Uri uri = Uri.parse("http://google.com");
2. Intent it = new Intent(Intent.ACTION_VIEW, uri);
3. startActivity(it);
显示地图
1. Uri uri = Uri.parse("geo:38.899533,-77.036476");
2. Intent it = new Intent(Intent.ACTION_VIEW, uri);
3. startActivity(it);
4. // 其他 geo URI 範例
5. //geo:latitude,longitude
6. //geo:latitude,longitude?z=zoom
7. //geo:0,0?q=my+street+address
8. //geo:0,0?q=business+near+city
9. //google.streetview:cbll=lat,lng&cbp=1,yaw,,pitch,zoom&mz=mapZoom
路径规划
1. Uri uri = Uri.parse("http://maps.google.com/maps?f=d&saddr=startLat%20startLng&daddr=endLat%20endLng&hl=en");
2. Intent it = new Intent(Intent.ACTION_VIEW, uri);
3. startActivity(it);
4. //where startLat, startLng, endLat, endLng are a long with 6 decimals like: 50.123456
打电话
1. // 叫出拨号程序
2. Uri uri = Uri.parse("tel:0800000123");
3. Intent it = new Intent(Intent.ACTION_DIAL, uri);
4. startActivity(it);
1. // 直接打电话出去
2. Uri uri = Uri.parse("tel:0800000123");
3. Intent it = new Intent(Intent.ACTION_CALL, uri);
4. startActivity(it);
5. // 用這個,要在 AndroidManifest.xml 中,加上
6. //<uses-permission id="android.permission.CALL_PHONE" />
传送 SMS/MMS
1. // 调用短信程序
2. Intent it = new Intent(Intent.ACTION_VIEW, uri);
3. it.putExtra("sms_body", "The SMS text");
4. it.setType("vnd.android-dir/mms-sms");
5. startActivity(it);
1. // 传送消息
2. Uri uri = Uri.parse("smsto://0800000123");
3. Intent it = new Intent(Intent.ACTION_SENDTO, uri);
4. it.putExtra("sms_body", "The SMS text");
5. startActivity(it);
1. // 传送 MMS
2. Uri uri = Uri.parse("content://media/external/images/media/23");
3. Intent it = new Intent(Intent.ACTION_SEND);
4. it.putExtra("sms_body", "some text");
5. it.putExtra(Intent.EXTRA_STREAM, uri);
6. it.setType("image/png");
7. startActivity(it);
传送 Email
1. Uri uri = Uri.parse("mailto:[email protected]");
2. Intent it = new Intent(Intent.ACTION_SENDTO, uri);
3. startActivity(it);
1. Intent it = new Intent(Intent.ACTION_SEND);
2. it.putExtra(Intent.EXTRA_EMAIL, "[email protected]");
3. it.putExtra(Intent.EXTRA_TEXT, "The email body text");
4. it.setType("text/plain");
5. startActivity(Intent.createChooser(it, "Choose Email Client"));
1. Intent it=new Intent(Intent.ACTION_SEND);
2. String[] tos={"[email protected]"};
3. String[] ccs={"[email protected]"};
4. it.putExtra(Intent.EXTRA_EMAIL, tos);
5. it.putExtra(Intent.EXTRA_CC, ccs);
6. it.putExtra(Intent.EXTRA_TEXT, "The email body text");
7. it.putExtra(Intent.EXTRA_SUBJECT, "The email subject text");
8. it.setType("message/rfc822");
9. startActivity(Intent.createChooser(it, "Choose Email Client"));
1. // 传送附件
2. Intent it = new Intent(Intent.ACTION_SEND);
3. it.putExtra(Intent.EXTRA_SUBJECT, "The email subject text");
4. it.putExtra(Intent.EXTRA_STREAM, "file:///sdcard/mysong.mp3");
5. sendIntent.setType("audio/mp3");
6. startActivity(Intent.createChooser(it, "Choose Email Client"));
播放多媒体
Uri uri = Uri.parse("file:///sdcard/song.mp3");
Intent it = new Intent(Intent.ACTION_VIEW, uri);
it.setType("audio/mp3");
startActivity(it);
Uri uri = Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI, "1");
Intent it = new Intent(Intent.ACTION_VIEW, uri);
startActivity(it);
Market 相关
1. // 寻找某个应用
2. Uri uri = Uri.parse("market://search?q=pname:pkg_name");
3. Intent it = new Intent(Intent.ACTION_VIEW, uri);
4. startActivity(it);
5. //where pkg_name is the full package path for an application
1. // 显示某个应用的相关信息
2. Uri uri = Uri.parse("market://details?id=app_id");
3. Intent it = new Intent(Intent.ACTION_VIEW, uri);
4. startActivity(it);
5. //where app_id is the application ID, find the ID
6. //by clicking on your application on Market home
7. //page, and notice the ID from the address bar
Uninstall 应用程序
1. Uri uri = Uri.fromParts("package", strPackageName, null);
2. Intent it = new Intent(Intent.ACTION_DELETE, uri);
3. startActivity(it);