美文网首页
《第一行代码》第三章 先从看得见的入手,探究Activity

《第一行代码》第三章 先从看得见的入手,探究Activity

作者: 番茄tomato | 来源:发表于2020-06-10 14:00 被阅读0次
  • 本篇参考资料《第一行代码 第三版》 2020.4月出版
  • 本篇文章只是本人看书的理解和整理的笔记,更完整的内容还在书上
  • 尊重原作者 请购买正版图书

确实Android没有非常系统的学习过,学艺不精,现在刚刚毕业面试几家公司,有很多基础的问题都答不上来。从头开始奋斗吧,根据书上的内容查漏补缺,保持两三天一章的节奏。

一 Activity基本用法

1.1 Activity 简介/创建/基本使用

书上内容详细 略

1.2 Activity 中的一些小玩意

使用Toast:

import kotlinx.android.synthetic.main.activity_main.*

     showToastBtn.setOnClickListener {
            Toast.makeText(this,"你点击了按钮",Toast.LENGTH_LONG).show()
        }

不需要使用findViewById了,Kotlin会直接为每个布局中的控件生成id同名对象,直接使用即可,但是要先引入:
import kotlinx.android.synthetic.main.activity_main.*
其他非常基础的部分书上都很清楚,不再赘述

二 使用Intent跳转到下一个Activity

2.1 显示Intent进行跳转
        jumpToSecondBtn.setOnClickListener {
            val intent:Intent=Intent(this,SecondActivity::class.java)
            startActivity(intent)
        }

这里SecondActivity::class.java就相当于JAVA中的SecondActivity.class

2.2 隐式Intent进行跳转
例子1:

在AndroidManifest的SecondActivity配置intent-filter

        <activity android:name=".activity.SecondActivity">
            <intent-filter>
                <action android:name="com.example.activitytest.ACTION_START"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
        </activity>

表示能SecondActivity能响应action为"com.example.activitytest.ACTION_START"的intent。category可以附带一些信息更加精确的指定Activity。
只有action和category同时匹配,才能打开Activity。接下来我们来看跳转代码:

        jumpToSecondBtn.setOnClickListener {
            val intent:Intent=Intent("com.example.activitytest.ACTION_START")
            startActivity(intent)
        }

可以看到这里使用了intent的另一个构造方法,指明了action。但是并没有配置category,事实上intent自己会配置一个默认的category也就是"android.intent.category.DEFAULT,刚好与我们之前AndroidManifest的SecondActivity配置的相匹配,所以可以打开第二个界面。下面我们自己配置一个category。

例子2:

配置category

        jumpToSecondBtn.setOnClickListener {
            val intent:Intent=Intent("com.example.activitytest.ACTION_START")
            intent.addCategory("com.example.activitytest.MY_CATEGORY")
            startActivity(intent)
        }

重新配置AndroidManifest的SecondActivity

        <activity android:name=".activity.SecondActivity">
            <intent-filter>
                <action android:name="com.example.activitytest.ACTION_START"/>
                <category android:name="android.intent.category.DEFAULT"/>
                <category android:name="com.example.activitytest.MY_CATEGORY"/>
            </intent-filter>
        </activity>

效果相同

一个intent可以配置多个category,一个Activity也可以配置多个category标签
只有intent的action和所有category都和Activity对应时,才能启动对应的Activity

2.2 隐式Intent扩展用法
2.1 启动外部应用

例子1:启动浏览器

        jumpToSecondBtn.setOnClickListener {
            val intent:Intent=Intent(Intent.ACTION_VIEW)
            intent.data= Uri.parse("https://www.baidu.com")
            startActivity(intent)
        }

点击打开系统浏览器并跳转到网页

这里指定Intent的action为Intent.ACTION_VIEW,这是系统内置的动作。
然后Uri.parse将网址解析为一个Uri对象,在调用Intent.setData,将对象传递进去。

例子2:内部Activity也响应这个网页打开intent

创建一个ThirdActivity,并配置如下内容:

        <activity android:name=".activity.ThirdActivity">
            <intent-filter tools:ignore="AppLinkUrlError">
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:scheme="https"/>
            </intent-filter>
        </activity>

在data标签中,使用 scheme 指定了数据协议必须是https
同样的
只有当action和data完全匹配时才能打开

打开后将会直接启动APP对应的Activity

接下来再运行:


image.png
例子3:启动系统拨号界面
        jumpToSecondBtn.setOnClickListener {
            val intent:Intent=Intent(Intent.ACTION_DIAL)
            intent.data= Uri.parse("tel:10086")
            startActivity(intent)
        }
2.3 Intent传递数据

这部分比较简单,已掌握,略过
注意startActivityForResult的使用
书中只涉及到intent传递单个字段,如果要传递某个数据实体对象该怎么操作?

2.4 Activity生命周期 P110详解
image.png

onCreate() 这个方法在Activity第一次被创建的时候调用。

onStart() 这个方法在Activity由不可见变为可见的时候调用。

onResume() 这个方法在Activity准备好和用户进行交互的时候调用。

onPause() 这个方法在系统准备去启动或者恢复另一个Activity的时候调用。

onStop() 这个方法在Activity完全不可见的时候调用。

onDestroy() 这个方法在Activity被销毁之前调用。

onRestart() 这个方法在Activity由停止状态变为运行状态之前调用,也就是Activity被重新启动了。

Activity被回收了该怎么办?例如先从A到B,但是这时A被回收了,那么B中点击返回,其实还是会显示A,但是是执行A的了onCreate()重新创建的。
显示界面倒是没有问题,但是A中的临时数据也没有了,该怎么办?
使用onSaveInstanceState

//保存数据
    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        val msg="hello world"
        outState.putString("data_key",msg)
    }
//恢复数据
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        if(savedInstanceState!=null){
            val msg=savedInstanceState.getString("data_key")
        }

}
2.5 Activity启动模式(面试遇到的问题 查漏补缺)

可以在AndroidManifest.xml中通过修改字段launchMode配置Activity启动模式:

        <activity
            android:name=".activity.MainActivity"
            android:label="MainActivity"
            android:launchMode="singleTask"
            >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

总共四种启动模式,简单总结一下:

standard
默认启动模式,无论返回栈中是否已经有Activity实例,都再次创建一个新的Activity实例
A-->A-->A可以无限叠加直到耗光内存

singleTop
如果Activity处于返回栈栈顶(目前呈现的界面),则不再创建实例,如果不再栈顶,则创建新的实例
A-->B-->A 可以无限叠加直到耗光内存
但是不能A-->A

singleTask
当返回栈中存在Activity实例时,不管它的位置在哪,直接呈现出来,不创建新的实例。原本在其之上的Activity则直接销毁。
例如返回栈:A-->B-->C-->D
这时执行D-->B,由于返回栈已经有B的实例,所以跳转后,C,D直接执行onDestroy
返回栈变为这样:A-->B

singleInstance
会为启动的Activity单独创建一个返回栈,这样其他程序共享这个Activity
比较复杂,书上的例子讲的很好理解,好好看好好学P124
书上的内容看懂了自然就理解下图了:

singleInstance.png
注意点:当一个返回栈空了的时候,会显示另一个返回栈的栈顶
2.6 Activity其他补充点

这部分小且杂的知识点参考书上
获取当前Activity类名----P126
在任意地方退出程序---P127

启动Activity的最佳写法:
例如从FirstActivity启动SecondActivity
现在可以很轻松的在FirstActivity中写出如下代码:

        jumpToSecondBtn.setOnClickListener {
            val intent:Intent=Intent(this,SecondActivity::class.java)
            intent.putExtra("data_name",10010)
            startActivity(intent)
        }

但是比如我们不清楚SecondActivity具体需要的参数,也不清楚其业务逻辑,这时就需要去阅读源码或者询问同事,这样会降低效率
其实可以通过以下方式
SecondActivity中加入如下代码:

companion object{
    fun actionStart(context: Context,data:Int){
        val intent:Intent=Intent(context,SecondActivity::class.java)
        intent.putExtra("data_name",data)
        context.startActivity(intent)
    }
}

然后再在FirstActivity中调用:

        jumpToSecondBtn.setOnClickListener {
            SecondActivity.actionStart(this, 10010)
        }

companion object的作用是让其中定义的方法可以像JAVA中静态方法进行调用。 P133

本章完

相关文章

网友评论

      本文标题:《第一行代码》第三章 先从看得见的入手,探究Activity

      本文链接:https://www.haomeiwen.com/subject/eykutktx.html