栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

《Android》Chap.3 探究Activity

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

《Android》Chap.3 探究Activity

Activity是⼀种可以包含用户界面的组件,主要用于和用户进行交互。

Activity的基本用法 创建和加载布局



    
属性介绍
  • id:给当前元素定义的
  • layout_width 和 layout_height:
    match_parent:全屏铺满
    wrap_content:自动根据内容调节大小
    20dp:数值设置 单位为dp
  • text:显示文字内容
  • textSize:设置文字大小 单位为sp
给Activity加载布局
setContentView(R.layout.first_layout)
在AndroidManifest文件中注册

  • android:label=""用于指定Activity中标题栏的内容

    
    

用于声明该Activity为主Activity

运行程序

(部分截图)

在Activity中使用Toast
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.first_layout)

    val button1: Button = findViewById(R.id.button1)
    button1.setOnClickListener{
        Toast.makeText(this,"You click Button1.",Toast.LENGTH_SHORT).show()
    }
}
补充kotlin特性:

使用Kotlin编写的Android项目在app/build.gradle文件的头部默认引入了⼀个kotlin-android-extensions插件,这个插件会根据布局文件中定义的控件id自动生成⼀个具有相同名称的变量,就可以在Activity里直接使用这个变量,而不用再调用findViewById()方法了

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.first_layout)

    button1.setOnClickListener {
        Toast.makeText(this,"You click Button1.",Toast.LENGTH_SHORT).show()
    }
}
运行程序

在Activity中使用Menu 文件路径

main.xml


    

    

这里创建了两个菜单项,其中标签用来创建具体的某⼀个菜单项,然后通过android:id给这个菜单项指定⼀个唯⼀的标识符,通过android:title给这个菜单项指定⼀个名称。

代码效果

重写onCreateOptionsMenu()方法
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
    menuInflater.inflate(R.menu.main,menu)
    return true
}
  1. inflate()中的两个参数:
    第⼀个参数用于指定通过哪⼀个资源文件来创建菜单,这里当然是传入R.menu.main
    第⼆个参数用于指定菜单项将添加到哪⼀个Menu对象当中,这里直接使用onCreateOptionsMenu()方法中传入的menu参数。
  2. 最后给这个方法返回true,表示允许创建的菜单显示出来。
重写onOptionsItemSelected()方法
override fun onOptionsItemSelected(item: MenuItem): Boolean {
    when (item.itemId) {
        R.id.add_item -> Toast.makeText(this,"You click Add",Toast.LENGTH_SHORT).show()
        R.id.remove_item -> Toast.makeText(this,"You click Remove",Toast.LENGTH_SHORT).show()
    }
    return true
}
运行代码

销毁Activity
finish()
使用Intent

Intent是Android程序中各组件之间进行交互的⼀种重要⽅方式,它不仅可以指明当前组件想要执行的动作,还可以在不同组件之间传递数据。Intent⼀般可⽤于启动Activity、启动Service以及发送广播等场景。

显式Intent

intent常用的构造函数接收两个参数:
第一个参数Context要求提供⼀个启动Activity的上下文
第二个参数Class用于指定想要启动的目标Activity
通过这个构造函数就可以构建出Intent的“意图”。
因为它的“意图”十分明显,所以称为显式Intent。

代码实现
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.first_layout)

    button1.setOnClickListener {
        val intent = Intent(this,SecondActivity::class.java)
        startActivity(intent)
    }
}
隐式Intent

隐式Intent并不明确指出想要启动哪⼀个Activity,而是指定了⼀系列更为抽象的action和category等信息,然后交由系统去分析这个Intent,并找出合适的Activity去启动。
通过在标签下配置的内容,可以指定当前Activity能够响应的action和category。

代码实现 AndroidManifest文件

FirstActivity
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.first_layout)

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

android.intent.category.DEFAULT是⼀种默认的category,在调用startActivity()方法的时候会自动将这个category添加到Intent中。

补充

每个Intent中只能指定⼀个action,但能指定多个category。目前我们的Intent中只有⼀个默认的categor,可以通过addCategory()方法添加。

intent.addCategory("com.example.activitytest.MY_CATEGORY")

其他用法1
button1.setOnClickListener {
    val intent = Intent(Intent.ACTION_VIEW)
    intent.data = Uri.parse("https://www.baidu.com")
    startActivity(intent)
}

⾸先指定了Intent的action是Intent.ACTION_VIEW,这是⼀个Android系统内置的动作,其常量值为android.intent.action.VIEW。然后通过Uri.parse()方法将⼀个网址字符串解析成⼀个Uri对象,再调用Intent的setData()方法将这个Uri对象传递进去。

这样在点击按钮时就可以看到在系统浏览器上打开了百度的网站

setData()方法接收⼀个Uri对象,用于指定当前Intent正在操作的数据,这些数据通常是以字符串形式传入Uri.parse()方法中解析产生的。

补充

与此对应,还可以在标签中再配置⼀个标签,用于更精确地指定当前Activity能够响应的数据。
标签中主要可以配置以下内容:

标签用途
android:scheme用于指定数据的协议部分,如上例中的https部分
android:host用于指定数据的主机名部分,如上例中的www.baidu.com部分
android:port用于指定数据的端口部分,⼀般紧随在主机名之后
android:path用于指定主机名和端口之后的部分,如⼀段网址中跟在域名之后的内容
android:mimeType用于指定可以处理的数据类型,允许使用通配符的方式进行指定

只有当标签中指定的内容和Intent中携带的Data完全⼀致时,当前Activity才能够响应该Intent。

实践


其他用法2
button1.setOnClickListener {
    val intent = Intent(Intent.ACTION_DIAL)
    intent.data = Uri.parse("tel:10086")
    startActivity(intent)
}

点击Button1后,自动跳转到电话并输入号码

向下一个Activity传递数据

Intent中提供了⼀系列putExtra()方法的重载,可以把我们想要传递的数据暂存在Intent中, 在启动另⼀个Activity后,只需要把这些数据从Intent中取出就可以了。
putExtra()方法接收两个参数,第⼀个参数是键,用于之后从Intent中取值,第⼆个参数才是真正要传递的数据。

class FirstActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.first_layout)

        button1.setOnClickListener {
            val data = "Hello SecondActivity"
            val intent = Intent(this,SecondActivity::class.java)
            intent.putExtra("extra_data",data)
            startActivity(intent)
        }
    }
}
class SecondActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_second)
        val extraData = intent.getStringExtra("extra_data")
        Log.d("SecondActivity","extra data is $extraData")
    }
}

向上一个Activity返回数据
class FirstActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.first_layout)

        button1.setOnClickListener {
            val intent = Intent(this,SecondActivity::class.java)
            startActivityForResult(intent,1)
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        when (requestCode) {
            1 -> if (resultCode == RESULT_OK){
                val returnData = data?.getStringExtra("data_return")
                Log.d("FirstActivity","returned data is $returnData")
            }
        }
    }
}
class SecondActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_second)
        button2.setOnClickListener {
            val intent = Intent()
            intent.putExtra("data_return","Hello FirstActivity")
            setResult(RESULT_OK,intent)
            finish()
        }
    }
}

Activity的生命周期

Android是通过任务来管理Activity,一个任务就是一组存放在栈里的Activity的集合,这个栈被称为返回栈(back stack)

Activity的4种状态
  • 运行态 Running:位于当前返回栈的顶部
  • 暂停态 Paused:不在栈顶但用户可见
  • 停止态 Stopped:不在栈顶且完全不可见
  • 销毁态 Destroyed:从返回栈中移除后销毁
Activity的7个回调方法
  1. onCreate():activity第一次启动时被调用,在该方法中初始化activity所能使用的全局资源和状态,如:绑定事件,创建线程等。
  2. onStart():当activity对用户可见时调用,即activity展现在前端,该方法一般用来初始化或启动与更新界面相关的资源
  3. onResume():当用户与activity进行交互时被调用,此时activity位于返回栈的栈顶,并处于运行状态,该方法完成一些轻量级的工作,避免用户等待
  4. onPause():启动或恢复另一个activity的时候被调用,该方法一般用来保存界面的持久信息,提交未保存的数据,并释放消耗CPU的资源。
  5. onStop():该方法在activity不可见状态时调用,如:其他activity启动或恢复并将其覆盖时调用。
  6. onDestroy():在activity销毁之前被调用。
  7. onRestart():当activity重新启动时调用。
Activity的3种生存期
  • 完整生成期:Activity 在onCreate()方法和onDestroy()方法之间所经历的,就是完整生存期。一般情况下,一个 Activity 会在onCreate()方法中完成各种初始化操作,而在onDestroy()方法中完成释放内存的操作。
  • 可见生存期: Activity 在onStart()方法和onStop()方法之间所经历的,就是可见生存期。在可见生存期内,Activity 对于用户总是可见的,即便有可能无法和用户进行交互。可以通过这两个方法,合理地管理那些对用户可见的资源。比如在onStart()方法中对资源进行加载,而在onStop()方法中对资源进行释放,从而保证处于停止状态的 Activity 不会占用过多内存。
  • 前台生存期:Activity 在onResume()方法和onPause()方法之间所经历的,就是前台生存期。在前台生存期内,Activity 总是处于运行状态的,此时的 Activity 是可以和用户进行交互的,我们平时看到和接触最多的也就是这个状态下的 Activity。
图解传送门 onSaveInstanceState()方法

onSaveInstanceState()方法会携带⼀个Bundle类型的参数,Bundle提供了⼀系列的方法用于保存数据。
比如可以使用putString()方法保存字符串,使用putInt()方法保存整型数据,以此类推。
每个保存方法需要传入两个参数,第⼀个参数是键,用于后面从Bundle中取值,第⼆个参数是真正要保存的内容。
该方法在Activity被回收之前一定会调用。

class FirstActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.first_layout)
        if (savedInstanceState != null) {
            val tempData = savedInstanceState.getString("data_key")
            Log.d("FirstActivity", "tempData is $tempData")
        }
    }

    override fun onSaveInstanceState(outState: Bundle, outPersistentState: PersistableBundle) {
        super.onSaveInstanceState(outState)
        val tempData = "Something you just typed"
        outState.putString("data_key", tempData)
    }
}
Activity的启动模式 standard

standard是Activity默认的启动模式。
在standard模式下,每当启动⼀个新的Activity,它就会在返回栈中入栈,并处于栈顶的位置。对于使用standard模式的Activity,系统不会在乎这个Activity是否已经在返回栈中存在,每次启动都会创建⼀个Activity的新实例。

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    Log.d("FirstActivity",this.toString())
    setContentView(R.layout.first_layout)

    button1.setOnClickListener {
        val intent = Intent(this,FirstActivity::class.java)
        startActivity(intent)
    }
}

singleTop

当Activity的启动模式指定为singleTop,在启动Activity时如果发现返回栈的栈顶已经是该Activity,则认为可以直接使用它,不会再创建新的Activity实例。
如果发现该Activity并未处于栈顶位置时,则创建一个新的Activity实例。

singleTask

当Activity的启动模式指定为singleTask,每次启动该Activity时,系统首先会在返回栈中检查是否存在该Activity的实例,如果发现已经存在则直接使用该实例,并把在这个Activity之上的所有其他Activity统统出栈,如果没有发现就会创建⼀个新的Activity实例。

singleInstance

指定为singleInstance模式的Activity会启用⼀个新的返回栈来管理这个Activity。
其实如果 singleTask 模式指定了不同的 taskAffinity,也会启动⼀个新的返回栈。

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.first_layout)
    Log.d("FirstActivity","Task id is $taskId")
    button1.setOnClickListener {
        val intent = Intent(this,SecondActivity::class.java)
        startActivity(intent)
    }
}
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    Log.d("SecondActivity","Task id is $taskId")
    setContentView(R.layout.activity_second)
    button2.setOnClickListener {
        val intent = Intent(this,ThirdActivity::class.java)
        startActivity(intent)
    }
}
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    Log.d("ThirdActivity","Task id is $taskId")
    setContentView(R.layout.activity_third)
}

Activity的最佳实践 知道当前在哪一个Activity
open class baseActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Log.d("baseActivity", javaClass.simpleName)
    }
}

让其他的活动都继承baseActivity。
然后运行程序,依次进入其他活动界面

随时随地退出程序

新建一个单例类ActivityCollector作为Activity的集合:

object ActivityCollector {

    private val activities = ArrayList()

    fun addActivity(activity: Activity){
        activities.add(activity)
    }
    
    fun removeActivity(activity: Activity){
        activities.remove(activity)
    }

    fun finishAll(){
        for (activity in activities){
            if (!activity.isFinishing){
                activity.finish()
            }
        }
        activities.clear()
    }
}

在baseActivity中添加:

在ThirdActivity中:

修改后,点击Button3则退出程序

启动Activity的最佳写法
companion object {
    fun actionStart(context: Context, data1: String,data2: String){
        val intent = Intent(context,SecondActivity::class.java)
        intent.putExtra("param1",data1)
        intent.putExtra("param2",data2)
        context.startActivity(intent)
    }
}


actionStart()方法中完成了Intent的构建,另外所有SecondActivity中需要的数据都是通过actionStart()方法的参数传递过来的,然后把它们存储到Intent中,最后调用startActivity()方法启动SecondActivity。
这样写最直接的好处就是⼀目了然,SecondActivity所需要的数据在方法参数中全部体现出来了

Kotlin课堂

未完待续

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/602151.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号