您当前的位置: 首页 >  android

代码与思维

暂无认证

  • 5浏览

    0关注

    163博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

想学好Android?这些高级技巧你都得会

代码与思维 发布时间:2022-05-05 13:53:53 ,浏览量:5

Android提供了一个Application类,每当应用程序启动的时候,系统就会自动将这个类进行初始化。如果我们想要在任何地方轻松获取Context,可以自己定制一个Application类,方便管理程序内的一些全局状态信息。

首先创建一个MyApplication类继承自Application:

class MyApplication: Application() {
    companion object{
        lateinit var context: Context
    }

    override fun onCreate() {
        super.onCreate()
        context = applicationContext
    }
}

我们先定义了一个context变量,然后重写了onCreate()方法,并调用getApplicationContext()方法的返回值赋给context变量,这样我们就可以以静态变量的形式获取Context对象了。

注意:将Context设置成静态变量很容易造成内存泄漏的问题,所以Android studio会提示有风险。实际上这里获取的并不是Activity或Service中的Context,而是Application中的Context,它全局只会存在一份实例,并且在整个应用程序的生命周期内都不会回收,因此是不存在内存泄漏的风险的。

我们可以Alt+Enter使用注解,让AS忽略警告:

    companion object{
        @SuppressLint("StaticFieldLeak")
        lateinit var context: Context
    }

此外,我们还需要告诉系统,当程序启动的时候应该初始化MyApplication类,而不是Application类。所以去到AndroidManifest.xml文件的标签下:


        ...

    

此时,在任何地方都可以调用MyApplication.context获取Context了。

2.使用Intent传递对象

我们在使用Intent传递数据的时候,putExtra()方法中所支持的数据类型是有限的,如果想要传递一些自定义对象就比较困难。这里就学习一下如何使用Intent来传递对象,有两种方式:Serializable和Parcelable。

2.1 Serializable方式

Serializable是序列化的意思,表示将一个对象转换成可存储或可传输的状态。序列化后的对象可以在网络上进行传输,也可以存储到本地。我们只需要让一个类去实现Serializable接口即可。

比如有一个Person类,包含name和age字段,想要序列化它,如下:

class Person : Serializable {
    var name = ""
    var age = 0
}

此时,所有的Person对象都可以序列化了。

在MainActivity中只需要这样写:

        val person = Person()
        person.name = "shuFu"
        person.age = 23
        val intent = Intent(this, SecondActivity::class.java)
        intent.putExtra("person_data", person)
        startActivity(intent)

然后在SecondActivity中获取这个对象,写法如下:

val person = intent.getSerializableExtra("person_data") as Person

操作很简单。

注意:这种传递对象的工作原理是先将一个对象序列化成可存储或可传输的状态,传递给另外一个Activity后再将其反序列化成一个新的对象。虽然这两个对象中存储的数据完全一致,但是它们实际上是不同的对象。

2.2 Parcelable方式

Parcelable也是实现相同的效果,不过它的原理是将一个完整的对象进行分解,分解后的每一部分都是Intent所支持的数据类型,这样就实现了传递对象的功能。

首先修改Person类中的代码:

class Person : Parcelable {
    var name = ""
    var age = 0

    override fun describeContents(): Int {
        return 0
    }

    override fun writeToParcel(p0: Parcel, p1: Int) {
        p0.writeString(name)   //写出name
        p0.writeInt(age)   //写出age
    }

    companion object CREATOR : Parcelable.Creator {
        override fun createFromParcel(p0: Parcel): Person {
            val person = Person()
            person.name = p0.readString() ?: ""    //读取name
            person.age = p0.readInt()              //读取age
            return person
        }

        override fun newArray(p0: Int): Array {
            return arrayOfNulls(p0)
        }
    }
}

首先实现Parcelable接口,重写describeContents()和writeToParcel()两个方法,第一个方法返回0即可,第二个方法需要调用Parcel的writeXxx()方法将Person类中的字段一一写出。然后还必须为Person类提供一个CREATOR的匿名类实现,这里创建了一个Parcelable.Creator接口的一个实现,泛型为Person。

然后再重写createFromParcel()和newArray()两个方法,第一个方法中需要创建一个Person对象并返回,同时要读取写出的字段,读取顺序一定要与写出顺序一致。第二个方法只需要调用arrayOfNulls()方法,并使用参数中传入的size作为数组大小,创建一个空的Person数组即可。

接着在MainActivity中的用法一样,只是要修改SecondActivity中的获取方式:

val person = intent.getParcelableExtra("person_data")

这种写法还是复杂,不过Kotlin提供了一种简便的用法,前提是要传递的所有数据都必须封装在对象的主构造函数中。

修改Person类:

@Parcelize
class Person(var name: String, var age: Int) : Parcelable{
}

只要把字段移到主构造函数中,然后添加注解即可。

3.定制自己的日志工具

如果我们在编程一个项目,期间为了方便调试,在很多地方都进行了打印日志,但是到了项目完成上线的时候,那些日志仍会打印,就会产生一些风险,但如果自己一行一行地去删,也显得太麻烦了。所以就需要做到能够控制日志的打印。项目开发时就打印,上线后就屏蔽掉。

接下来就定制一个日志工具,新建一个LogUtil单例类:

object LogUtil {
    private const val VERBOSE = 1
    private const val DEBUG = 2
    private const val INFO = 3
    private const val WARN = 4
    private const val ERROR = 5
    private var level = VERBOSE
    fun v(tag: String, msg: String) {
        if (level 
                
关注
打赏
1665387627
查看更多评论
0.0386s