1.1. 设计并实现用户接口
1.2. 配置manifest
<activity android:name=".ExampleActivity" />
过滤器的作用就是声明其他 app 组件是如何激活该 activity 的
下面过滤器声明本 activity 对"main"动作进行响应,并处于"launcher"这个类别中<intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter>
android:permission="com.google.socialapp.permission.SHARE_POST" //定义权限 <uses-permission android:name="com.google.socialapp.permission.SHARE_POST" /> //声明权限
1.3. 启动 Activity
Intent intent = new Intent(this, SignInActivity.class); //从 this 启动 SignInActivity startActivity(intent);
例如你想允许用户发送电子邮件,可以创建以下 Intent:
Intent intent = new Intent(Intent.ACTION_SEND); //这个和等同于 intent.setAction intent.putExtra(Intent.EXTRA_EMAIL, recipientArray); startActivity(intent);
private void pickContact() { // Create an intent to "pick" a contact, as defined by the content provider URI Intent intent = new Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI); startActivityForResult(intent, PICK_CONTACT_REQUEST); } //PICK_CONTACT_REQUEST,主调和被调之间的暗号,自定义的常量 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { // If the request went well (OK) and the request was PICK_CONTACT_REQUEST if (resultCode == Activity.RESULT_OK && requestCode == PICK_CONTACT_REQUEST) { // Perform a query to the contact's content provider for the contact's name Cursor cursor = getContentResolver().query(data.getData(), new String[] {Contacts.DISPLAY_NAME}, null, null, null); if (cursor.moveToFirst()) { // True if the cursor is not empty int columnIndex = cursor.getColumnIndex(Contacts.DISPLAY_NAME); String name = cursor.getString(columnIndex); // Do something with the selected contact's name... } } } //resultCode == Activity.RESULT_OK,被调正确执行并返回正确结果 //requestCode == PICK_CONTACT_REQUEST,请求码,通过暗号判断结果是返回给谁的
1.4. 关闭一个Activity
finish()
方法或者finishActivity (int requestCode)
来关闭一个 activity,代码出现错误 记得 import 对应的类
2.1. 响应 Send 按钮
在相应的 MainActivity.java 中添加方法 如sendMessage()
android:onClick
属性值,该方法必须满足:2.2. 构建一个Intent
例:显式Intent 通过 putExtra 方法添加 “额外" 数据信息
public static final String EXTRA_MESSAGE = "com.example.myfirstapp.MESSAGE"; public void sendMessage(View view) { Intent intent = new Intent(this, DisplayMessageActivity.class); EditText editText = (EditText) findViewById(R.id.editText); String message = editText.getText().toString(); //将这个文本字符串以键值对的形式附加到 Intent 中, //通常我们用应用的包名作为前缀,以保证键的唯一性 intent.putExtra(EXTRA_MESSAGE, message); //通过 intent 启动另一个 activity,同时传递数据 startActivity(intent); }
2.3. 创建第二个 Activity
2.4. 显示消息
//获取启动本 activity 的 Intent Intent intent = getIntent(); //从该 Intent 中提取传递过来的数据 String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE); TextView textView = findViewById(R.id.textView); textView.setText(message)
2.5. 添加向上导航
就是指明该 Activity 的逻辑父项<activity android:name=".DisplayMessageActivity" android:parentActivityName=".MainActivity" >
Activity 的三个稳定状态:继续 (Resumed)、暂停 (Paused)、停止 (Stopped)
六个生命周期方法:onCreate(), onStart(), onResume(), onPause(), onStop(), 和 onDestroy()
3.1. 实现生命周期回调方法
3.2. 调用onCreate()方法启动Activity
3.3. Activity生命周期的最后一个回调方法onDestroy()
3.4. 暂停及重启一个Activity
3.5. 停止和重启activity
3.6. 保存 Activity 状态
static final String STATE_SCORE = "playerScore";
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// 保存用户当前的游戏状态
savedInstanceState.putInt(STATE_SCORE, mCurrentScore);
// 总是首先调用父类中的onSaveInstanceState方法
super.onSaveInstanceState(savedInstanceState);
}
当用户离开你的activity时,系统调用这个方法并传递一个Bundle对象,如果系统必须重建该activity实例的时候,会把同一个Bundle对象传递给onRestoreInstanceState()和onCreate()方法
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); // 总是首先调用父类中的 onCreate方法
// 检查我们是否是在重建以前销毁的本 Activity的实例
if (savedInstanceState != null) {
// 从保存的状态中恢复成员的值
mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
} else {
// 新实例中的变量可能需要用默认值进行初始化
}
}
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
// 从保存实例中恢复状态变量值
mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
}
3.7. 重建一个activity
3.8. 协调 Activity
启动第二个 Activity 的过程与停止第一个 Activity 的过程存在重叠
3.9. Activity 生命周期回调方法汇总表
一个 task 就是一个用户用于完成某项工作的 activity 集合
这些 activity 以栈 (back stack) 来进行管理
4.1. standard(默认)
4.2. singleTop
4.3. singleTask
4.4. singleInstance
Intent 是一个消息传递对象,可以使用它从其他应用组件请求操作
5.1. Intent 类型
5.2. 构建 Intent
组件名称、操作、数据、类别;Extra、标志
用 setDataAndType() 同时设置 URI 和 MIME 类型
// 因为是在 Activity中执行,因此,'this'是指本 Activity
// fileUrl是一个字符串 URL, 比如 "http://www.example.com/image.png"
Intent downloadIntent = new Intent(this, DownloadService.class);
downloadIntent.setData(Uri.parse(fileUrl));
startService(downloadIntent);
// 使用字符串创建文本消息
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, textMessage);
sendIntent.setType("text/plain");
//系统并没有使用 URI,但已声明 Intent 的数据类型,用于指定 extra 携带的内容
// 验证是否有 activity处理该 Intent
if (sendIntent.resolveActivity(getPackageManager()) != null) {
startActivity(sendIntent);
}
Intent intent = new Intent(Intent.ACTION_SEND);
// UI中的文字要使用字符串资源 something like "Share this photo with"
String title = getResources().getString(R.string.chooser_title);
// Create intent to show the chooser dialog 强制创建应用选择器
Intent chooser = Intent.createChooser(intent, title);
// Verify the original intent will resolve to at least one activity
if (sendIntent.resolveActivity(getPackageManager()) != null) {
startActivity(chooser);
}
5.3. 接收隐式 Intent
action
:在 name 属性中,声明接受的 Intent 操作,必须是文本字符串data
:使用一个或多个指定数据 URI 各个方面(scheme、host、port、path 等)和 MIME 类型的属性,声明接受的数据类型category
:在 name 属性中,声明接受的 Intent 类别,必须是文本字符串exported
属性设置为 "false"
5.4. 使用待定 Intent(略)*
5.5. Intent 解析
<scheme>://<host>:<port>/<path>
6.1. 把用户转向另一个应用
查看网页:
Uri webpage = Uri.parse("http://www.android.com");
Intent webIntent = new Intent(Intent.ACTION_VIEW, webpage);
可以通过 putExtra 来添加额外的数据
6.1.2. 验证是否存在接收 Intent 的应用
PackageManager packageManager = getPackageManager();
List activities = packageManager.queryIntentActivities(intent, 0); //0处:PackageManager.MATCH_DEFAULT_ONLY
boolean isIntentSafe = activities.size() > 0;
if (isIntentSafe) {
startActivity(intent);
}
6.2. 获取 Activity 的返回结果
响应的 Activity 必须设计为返回结果,如下:
public void returnTOMain(View view) {
EditText editText = (EditText)findViewById(R.id.ap_et_inputPhoneNumber);
String phoneNumber = editText.getText().toString();
Intent result = new Intent("com.example.RESULT_ACTION", Uri.parse(phoneNumber));
setResult(Activity.RESULT_OK, result);
finish();
}
6.3. 启动activity
startActivityForResult(intent, REQUEST_CODE)
第二个参数,用于标识你的请求
6.4. 接收结果
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// Check which request we're responding to
if (requestCode == PICK_CONTACT_REQUEST) {
// Make sure the request was successful
if (resultCode == RESULT_OK) {
TextView textView = (TextView)findViewById(R.id.ma_tv_phoneNumber);
textView.setText(data.getDataString());
}
}
}
7.1. 添加 Intent 过滤器
7.2. 处理您的 Activity 中的 Intent
通常应在 onCreate() 和 onStart() 中执行 getIntent()
Intent intent = getIntent();
Uri data = intent.getData();
// Figure out what to do based on the intent type
if (intent.getType().indexOf("image/") != -1) {
// Handle intents with image data ...
} else if (intent.getType().equals("text/plain")) {
// Handle intents with text ...
}
7.3. 返回结果
只管调用 setResult,若 Intent 调用的是 startActivity,会自动忽略
// Create intent to deliver some kind of result data
Intent result = new Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri"));
setResult(Activity.RESULT_OK, result);
finish();
附:task与back栈
- 当用户启动一个新的task或者是使用Home按钮回到Home屏,task可以作为一个整体移入后台。当在后台的时候,task中的所有activity都停止了,但是back栈还保持完整,只是失去焦点而已
- 多个 task 处于后台时,系统可能会销毁后台 activity 来收回内存,这会引起 activity 状态的丢失
- activity 停止时,系统会保持它的状态
- Activity可以被多次实例化,甚至在其他task中
2.1. 定义加载(launch)模式
2.2. 使用manifest文件
四个模式,launchMode 属性的四种值
2.3. 使用Intent标志
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2.4. 处理affinity
affinity表示一个activity属于哪个task
2.5. 清除back栈
用户离开 task 时间较长
2.6. 启动一个task
action.MAIN 和 category.LAUNCHER 配对使用
End.