2020/07/08课后作业

Q1:对Intent和intent-filter的action进行研究和尝试,知道Intent和intent-filter的匹配规则?

使用隐式 Intent 时,系统通过将 Intent 中的action、data、category 与 intent-filter 的内容进行匹配,
只有action、data、category这三部分都匹配成功,这个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 的代理类,

主要区别是 ContextThemeWrapper 有自己的主题资源。它们继承关系如下:

 

简单的浏览一下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

 

posted @ 2020-07-08 21:34  高昶  阅读(185)  评论(0编辑  收藏  举报