2020/07/08课后作业
Q1:对Intent和intent-filter的action进行研究和尝试,知道Intent和intent-filter的匹配规则?
补:对今天考题的研究::Intent中如果存在categary,那么所有的category都必须和intent-filter中相同。
如果不含category,也可以匹配成功,因为在startActivity()中会默认给intent添加“android.intent.category.DEFAULT”。
因此,要想acitivity接受隐式Intent,则必须在intent-filter中添加此category。
Q2: 研究Intent如何传递自定义的java对象,实现的demo截图以及文字描述?
主要有两种方式:1、Serializable方式(Java机制下);2、Parcelable方式(Android特有)
我们这里创建两个不同的实体类:User、Song。
User implements Serializable Song implements Parcelable
在MainActivity中写两个按钮,用来执行两种不同的方法:
case R.id.btn_sz:
User user = new User();
user.setUsername("高昶");
user.setPassword("520520");
Intent intent = new Intent(this, UserActivity.class);
intent.putExtra("user", user);
intent.putExtra("from", "Serializable"); //UserActivity中用来区分类别
startActivity(intent);
break;
case R.id.btn_pa:
Song song = new Song();
song.setAuthor("周杰伦");
song.setNumber(100000);
Intent intent2 = new Intent(this, UserActivity.class);
intent2.putExtra("song", song);
intent2.putExtra("from", "Parcelable");
startActivity(intent2);
break;
在UserActivity中去接收数据:
private void getExtra() {
String type = getIntent().getStringExtra("from");
if (type.equals("Serializable")) {
User user = (User) getIntent().getSerializableExtra("user");
Log.i(TAG, "用户名:" + user.getUsername() + ";密码:" + user.getPassword());
} else if (type.equals("Parcelable")) {
Song song = (Song) getIntent().getParcelableExtra("song");
Log.i(TAG, "歌手名:" + song.getAuthor() + ";播放数:" + song.getNumber());
}
}
我们来看一下两次点击按钮后Log打印的结果:

Q3:简单了解Context和可序列化
Context字面意思上下文,Context 本身是一个抽象类,主要实现类为 ContextImpl,另外有子类 ContextWrapper 和 ContextThemeWrapper,这两个子类都是 Context 的代理类,

简单的浏览一下Context源码,我们就看一下有关四大组件相关的代码,可以发现Context 就相当于 Application的管理者,负责四大组件的交互等。
// 四大组件相关
public abstract void startActivity(@RequiresPermission Intent intent);
public abstract void sendBroadcast(@RequiresPermission Intent intent);
public abstract Intent registerReceiver(@Nullable BroadcastReceiver receiver,
IntentFilter filter);
public abstract void unregisterReceiver(BroadcastReceiver receiver);
public abstract ComponentName startService(Intent service);
public abstract boolean stopService(Intent service);
public abstract boolean bindService(@RequiresPermission Intent service,
@NonNull ServiceConnection conn, @BindServiceFlags int flags);
public abstract void unbindService(@NonNull ServiceConnection conn);
public abstract ContentResolver getContentResolver();
序列化是干什么的?
简单说就是为了保存在内存中的各种对象的状态(也就是实例变量,不是方法),并且可以把保存的对象状态再读出来。
虽然你可以用你自己的各种各样的方法来保存object states,但是Java给你提供一种应该比你自己好的保存对象状态的机制,那就是序列化。
为什么Intent中传递实体类要序列化?
Intent传递数据是能够在不同的进程间传输的,Android是基于Linux系统,不同进程之间的java对象是无法传输,所以我们此处要对对象进行序列化。
Q4: 研究Activity的常用方法,onActivityResult和startActivityForResult要实现一个demo截图
首先在MainActivity中写一个按钮来监听事件:
case R.id.btn_tr:
Intent intent3 = new Intent(MainActivity.this, ResultActivity.class);
intent3.putExtra("msg", "我是MainActivity,你是谁?");
startActivityForResult(intent3, CODE_FOR_REQUEST);
break;
在MainActivity 重写onActivityResult的方法:
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1 && resultCode == 2) {
String result = data.getStringExtra("result");
Log.i(TAG, result);
}
}
然后在ResultActivity中设置相应的返回内容:
case R.id.btn_back:
Log.i(MainActivity.TAG, getIntent().getStringExtra("msg"));
Intent intent = new Intent();
intent.putExtra("result", "收到,我是ResultActivity");
setResult(CODE_FOR_RESULT, intent);
finish();
break;
来看一下Log结果:

Q5:通过页面跳转尝试启动模式demo任务栈和任务实例情况,log关键信息截图
首先我们先写一下相应的Activity并在清单文件中配置:
<activity
android:name=".activity.SingleTaskActivity"
android:launchMode="singleTask" />
<activity
android:name=".activity.SingleTopActivity"
android:launchMode="singleTop" />
<activity
android:name=".activity.SingleInstanceActivity"
android:launchMode="singleInstance" />
<activity
android:name=".activity.StandardActivity"
android:launchMode="standard">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
然后写一下相应的跳转的逻辑:
switch (v.getId()) {
default:
break;
case R.id.btn_tz1:
startActivity(new Intent(this, SingleInstanceActivity.class));
Log.i("lunchMode", "跳转记录:" + getClass().getSimpleName() + "----->SingleInstanceActivity");
break;
case R.id.btn_tz2:
startActivity(new Intent(this, SingleTaskActivity.class));
Log.i("lunchMode", "跳转记录:" + getClass().getSimpleName() + "----->SingleTaskActivity");
break;
case R.id.btn_tz3:
startActivity(new Intent(this, SingleTopActivity.class));
Log.i("lunchMode", "跳转记录:" + getClass().getSimpleName() + "----->SingleTopActivity");
break;
case R.id.btn_tz4:
startActivity(new Intent(this, StandardActivity.class));
Log.i("lunchMode", "跳转记录:" + getClass().getSimpleName() + "----->StandardActivity");
break;
}
点击相应的按钮跳转:

然后查看Activity栈里面的内容:

符合期望!
再看看其他的:


本人目前知识掌握有限,很多地方还处在不足,还请指正。
附上Demo地址:https://gitee.com/XiaoXiaoChang/demo

浙公网安备 33010602011771号