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