第一行代码Android个人笔记(一)——activity的基本用法

本节内容对应《第一行代码 第三版》:第三章

文章目录

    • 一、在AndroidManifest中注册
      • Manifest简介
      • 的用处
    • 二、Activity导航
      • 1.显式导航
      • 2.隐式Intent
      • 3.传递数据
    • 三、菜单
    • 四、Activity的生命周期
    • 五、 在Activity被回收时保存数据
    • 六、Activity的启动模式
    • 七、kotlin标准函数with/run/apply
    • 八、Kotlin中的静态方法

一、在AndroidManifest中注册

Manifest简介

如果我们创建了一个空的项目(no activity),自己新建了一个FirstActivity,此时需要在Manifest中手动注册。
幸运的是,AS已经为我们写好了以下代码

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.lrgy.activitytest">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".FirstActivity">
        </activity>
    </application>

</manifest>

其中,com.lrgy.activitytest表示应用整体的包名,android:name=".FirstActivity"表示这个application具体注册了com.lrgy.activitytest.FirstActivity这个Activity。
我们需要指定程序运行时首先启动哪个Activity,即在标签中添加标签

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

这两个标签指明了应用启动时首先启动该Activity

的用处

另外,这个标签还有额外的作用,即在里面添加标签
· intent介绍见:Intent 和 Intent 过滤器

  • 指定该Activity可以响应com.lrgy.activitytest.ACTION_START这个动作,这个动作名可以自己写,只需要和隐式Intent中val intent = Intent("com.lrgy.activitytest.ACTION_START")传入的参数相同即可
<action android:name="com.lrgy.activitytest.ACTION_START" />
  • 指定详细信息,android.intent.category.DEFAULT表示不设置category(即默认category)时响应
<category android:name="android.intent.category.DEFAULT" />
  • data,如下操作可以响应链接,不过需要在标签中添加tools:ignore="AppLinkUrlError"
<activity android:name=".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>

二、Activity导航

1.显式导航

//构建Intent对象,参数:上下文Context,目的地Activity
val intent = Intent(this, SecondActivity::class.java)

//执行intent
startActivity(intent)

2.隐式Intent

            val intent = Intent("com.lrgy.activitytest.ACTION_START")//传入要响应界面的action值
            intent.addCategory()//传入要响应界面的category值,也可以不设置,即默认
            startActivity(intent)
  • 实现打开浏览器访问百度
            val intent = Intent(Intent.ACTION_VIEW)         //内置动作,跳转至其他应用
            intent.data = Uri.parse("https://baidu.com")    //接受Uri对象,设置目的uri
            startActivity(intent)

3.传递数据

  • 向下一个Activity传递

发送:

intent.putExtra("extra_data", "携带的信息")

接收:

intent.getStringExtra("extra_data")
  • 返回给上一个Activity

接受:

startActivityForResult(intent,10086)//带有返回结果的导航,10086是请求码,在这里设置
//重写onActivityResult方法,requestCode是请求码,resultCode是处理结果如RESULT_OK,data是回传的Intent
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
     
        super.onActivityResult(requestCode, resultCode, data)
        when(requestCode){
     
            10086 -> Log.d("mydebug", "收到下层反馈")
        }
    }

发送:

//按下返回键即调用该方法
override fun onBackPressed() {
     
        super.onBackPressed()
        val intent = Intent()
        intent.putExtra("data_return","返回给上层的数据")
        setResult(RESULT_OK,intent)//第一个参数是向上返回结果,用RESULT_OK就行
        finish()
    }

三、菜单

  1. 创建menu资源,使用指定菜单项
<item
        android:id="@+id/add_item"
        android:title="Add"/>
  1. 重写创建菜单方法
//创建菜单,即在Activity中重写该方法
    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
     
        
        //传入menu资源和要添加至的Menu对象,后者一般用onCreateOptionsMenu中自带参数menu
        menuInflater.inflate(R.menu.main, menu)
        
        //return true才能显示菜单
        return true                                        
    }
  1. 重写菜单选择方法
override fun onOptionsItemSelected(item: MenuItem): Boolean {
     
        when(item.itemId){
     

            //使用toast弹出框。参数:上下文上下文Context、显示内容、常量LENGTH_SHORT或Toast.LENGTH_LONG
            R.id.add_item -> Toast.makeText(this,"add item",Toast.LENGTH_SHORT).show()
            R.id.remove_item -> Toast.makeText(this,"remove item",Toast.LENGTH_LONG).show()
        }

        /*关于返回值
          有人说:
        * true表示该方法执行完毕后,点击事件不会再向下一个事件处理方法传递了。
        * false表示执行完该方法后,点击事件继续向下传递。
        * */
        return false
    }

四、Activity的生命周期

详解见:Android Activity生命周期详解

五、 在Activity被回收时保存数据

fun onSaveInstanceState(outState: Bundle, outPersistentState: PersistableBundle)这个函数将会在Activity被回收前调用,我们可以把数据存放在outState: Bundle中。

override fun onSaveInstanceState(outState: Bundle, outPersistentState: PersistableBundle) {
     
        super.onSaveInstanceState(outState, outPersistentState)
        val tempData = "something you want to save"
        outState.putString("data_key",tempData)
    }

然后在onCreate中使用savedInstanceState: Bundle?取出数据

override fun onCreate(savedInstanceState: Bundle?) {
     
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        savedInstanceState?.let {
     
            Log.d(tag,it.getString("data_key"))
        }
    }

PS:关于手机屏幕旋转导致Activity重建的问题,我们有更优雅的解决方法,在13.2节

六、Activity的启动模式

通过在AndroidManifest.xml中的标签可以指定启动方式

<activity
      android:name=".FirstActivity"
      android:launchMode="standard">
      
activity>
  1. standard
    即默认启动模式,不断创建新的FirstActivity实例
  2. singleTop
    若FirstActivity在返回栈的顶端,则不创建新的实例
  3. singleTask
    保持应用只有一个FirstActivity实例
  4. singleInstance
    创建新的返回栈,放入新的栈中

七、kotlin标准函数with/run/apply

  • 原生:
val list = listOf<String>("apple", "banana", "pear", "orange")
    val builder = StringBuilder()
    builder.append("start eating fruits...\n")
    for (fruit in list){
     
        builder.append(fruit).append("\n")
    }
    builder.append("ate all fruits.")
    val result = builder.toString()
    println(result)
  • with
val result2 = with(StringBuilder()){
     
        append("start eating fruits...\n")
        for (fruit in list){
     
            append(fruit).append("\n")
        }
        append("ate all fruits.")
        toString()
    }
    println(result2)
  • run
val result3 = StringBuilder().run{
     
        append("start eating fruits...\n")
        for (fruit in list){
     
            append(fruit).append("\n")
        }
        append("ate all fruits.")
        toString()
    }
    println(result3)
  • apply
val result4 = StringBuilder().apply{
     
        append("start eating fruits...\n")
        for (fruit in list){
     
            append(fruit).append("\n")
        }
        append("ate all fruits.")
    }
    println(result4.toString())

八、Kotlin中的静态方法

  1. 使用单例类(伪静态方法,会创建单例类)
object Util {
     
    fun doAction(){
     
        println("do action")
    }
}
  1. 使用companion object(伪静态方法,会创建单例类)
class Util {
     
    companion object{
     
        fun doAction(){
     
            println("do action")
        }
    }
}
  1. 使用companion object加注解JvmStatic(真静态方法)
class Util {
     
    companion object{
     
        @JvmStatic
        fun doAction(){
     
            println("do action")
        }
    }
}
  1. 使用顶层方法,即没有类的方法
package com.lrgy.activitytest

fun doAction(){
     
    println("do action")
}

在Kotlin中直接用方法名调用,JAVA中用文件名Kt.方法名调用

你可能感兴趣的:(Android开发技术,android)