这边文章主要详细介绍多进程的实现,以及用contenprovider 来实现进程中的通信,最后会附上github代码
做了几年的android之后,慢慢的就会接触到 多进程方面,那么为什么要用多进程呢
有以下几个选项:
1.可以装比
2.可以撩妹
3.学习使我快乐
4.博主最帅
没错,就是第四个选项,
好了,废话不多说,不知道为啥用多进程自己谷歌去,接下来开始多进程讲解,
如图建立个项目:(以后所有项目都会传到gitgub上,供方便下载)
如图所示,为当前项目目录,有2个test activity ,没错开在不同的进程,
通过给activity 加上process 属性 让该activity 单独运行在该进程下,通过log的打印得知:
test1 :processName-=-==-=-=-=>com.example.licheng.contentprovidertest
test2 : processName-=-==-=-=-=>com.example.licheng.contentprovidertest:test2
然后我们在application里面写入get,set方法,然后在test1 中赋值,在test2中 get值 试试,
package com.example.licheng.contentprovidertest.base
import android.app.ActivityManager
import android.app.Application
import android.content.Context
import android.util.Log
class TestAppliaction : Application() {
companion object {
private var instance: TestAppliaction? = null
get() {
if (field == null) {
field = TestAppliaction()
}
return field
}
fun get(): TestAppliaction{
//细心的小伙伴肯定发现了,这里不用getInstance作为为方法名,是因为在伴生对象声明时,内部已有getInstance方法,所以只能取其他名字
return instance!!
}
}
//
// companion object {
// val instance: TestAppliaction by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
// TestAppliaction() }
// }
var valueme: String = ""
override fun onCreate() {
super.onCreate()
Log.i("Test", "TestAppliaction-=-==-=-=-=>" + getName())
}
fun getName(): String {
val pid = android.os.Process.myPid()//获取进程pid
var processName = ""
val am = this.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager//获取系统的ActivityManager服务
for (appProcess in am.runningAppProcesses) {
if (appProcess.pid == pid) {
processName = appProcess.processName
break
}
}
return processName
}
fun setValue(var1:String){
valueme=var1
}
fun getValue():String{
return valueme
}
}
以下为 test1,test2,
package com.example.licheng.contentprovidertest
import android.app.ActivityManager
import android.content.Context
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.util.Log
import com.example.licheng.contentprovidertest.base.TestAppliaction
import kotlinx.android.synthetic.main.activity_test1.*
class TestActivity1 : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_test1)
Log.i("Test", "processName-=-==-=-=-=>" + getName())
btn.setOnClickListener {
TestAppliaction.get().valueme="test1"
var value= TestAppliaction.get().getValue()
Log.i("Test", "Test1-=-==-=-=-=>" + value)
}
}
fun getName(): String {
val pid = android.os.Process.myPid()//获取进程pid
var processName = ""
val am = this.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager//获取系统的ActivityManager服务
for (appProcess in am.runningAppProcesses) {
if (appProcess.pid == pid) {
processName = appProcess.processName
break
}
}
return processName
}
}
package com.example.licheng.contentprovidertest
import android.app.ActivityManager
import android.content.Context
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.util.Log
import com.example.licheng.contentprovidertest.base.TestAppliaction
import kotlinx.android.synthetic.main.activity_test2.*
class TestActivity2 : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_test2)
Log.i("Test", "processName-=-==-=-=-=>" + getName())
btn.setOnClickListener {
var value= TestAppliaction.get().getValue()
Log.i("Test", "Test1-=-==-=-=-=>" + value)
}
}
fun getName(): String {
val pid = android.os.Process.myPid()//获取进程pid
var processName = ""
val am = this.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager//获取系统的ActivityManager服务
for (appProcess in am.runningAppProcesses) {
// if (appProcess.pid == pid) {
processName = appProcess.processName
break
// }
}
return processName
}
}
然后,打印日志,发现 ,我在test1 里面设置的值 在test2中 通过get方法获取不到,
没错,确实获取不到,why,这里要说到多进程下的application 来,每开一个进程 都会创建一次application,比如我打开了test2,这个时候相当于在 test2进程下,也有一个与之对应的application,在test1中获取的是test1进程下的application,在test2中获取到的 test2进程下的application,不同进程下的数据不能通过get set这种方法进行共享,那么问题来了,怎么进行数据共享呢,有方法,而且有很多方法,
今天就用contenprovider来说:
在说contenprovider之前,首页要了解为啥要用这个,
大部分说法很模糊,进程间的数据共享,我共享你个皮皮虾哦,我就被带沟里去了,
真--- 应用场景: 注意:多个应用之间共享数据,主要是多个应用之间,虽然单独的应用也可以用,但是给我的感觉主要还是针对多个应用之间交流数据
于是我创了另外一个工程,来调用第一个工程提供出来的contentprovider,注意,在注册的时候,需要
<provider android:exported="true" android:authorities="cn.scu.myprovider" android:name=".provider.MyProvider"></provider>
把android:exported 设置为true,这样才能在应用见共享,不然会报全县问题,如果在 单独的应用使用contentprovider,则随便设置,true 或者false 都可以,
以下为github 地址
项目demo https://github.com/jimoyefeng/contentProviderDemo.git
测试demo https://github.com/jimoyefeng/Testprovier.git