- 本篇参考资料《第一行代码 第三版》 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
接下来再运行:

例子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详解

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
书上的内容看懂了自然就理解下图了:

注意点:当一个返回栈空了的时候,会显示另一个返回栈的栈顶
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
本章完
网友评论