当在代码里面引入多进程时,会出现Application类多次调用,通过一个例子来看下打印。
- 首先定义一个MyApplication类,继承自Application类,别忘记在AndroidManifest.xml文件中声明。
public class MyApplication extends Application {
private static final String TAG = "MyApplication";
@Override
public void onCreate() {
super.onCreate();
A();
}
private void A() {
Log.i(TAG, "调用A方法");
}
}
- 然后定义一个服务
public class MyService extends Service {
public MyService() {
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
在AndroidManifest.xml文件中声明如下:
<service
android:name=".MyService"
android:enabled="true"
android:exported="true"
android:process=":myservice"/>
注意**android:process=":myservice"**这句话为MyService为当前程序子进程中运行。
- 在MainActivity中启动服务
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent i = new Intent(this, MyService.class);
startService(i);
}
@Override
protected void onDestroy() {
Intent i = new Intent(this, MyService.class);
stopService(i);
super.onDestroy();
}
}
观察打印
为方便观察,增加打印进程名方法
/**
* 获取当前进程名
*/
private String getCurrentProcessName() {
int pid = android.os.Process.myPid();
String processName = "";
ActivityManager manager = (ActivityManager) getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningAppProcessInfo process : manager.getRunningAppProcesses()) {
if (process.pid == pid) {
processName = process.processName;
}
}
return processName;
}
打印如下:
可以看到MyApplication类执行了两次,A方法也打印了两次。
- 要求A方法在主进程中执行一次,可在MyApplication加上如下判断,完整代码如下:
public class MyApplication extends Application {
private static final String TAG = "MyApplication";
@Override
public void onCreate() {
super.onCreate();
if (isMainProcess()) {
A();
}
}
private void A() {
Log.i(TAG, getCurrentProcessName() + ",调用A方法");
}
/**
* 获取当前进程名
*/
private String getCurrentProcessName() {
int pid = android.os.Process.myPid();
String processName = "";
ActivityManager manager = (ActivityManager) getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningAppProcessInfo process : manager.getRunningAppProcesses()) {
if (process.pid == pid) {
processName = process.processName;
}
}
return processName;
}
/**
* 包名判断是否为主进程
*
* @param
* @return
*/
public boolean isMainProcess() {
return getApplicationContext().getPackageName().equals(getCurrentProcessName());
}
}
修改MyApplication代码,执行,观察打印:
可以看到A方法只在主进程中执行一次。
主要原理是通过当前进程的pid获取当前进程名与包名比较判断是否是主进程
/**
* 包名判断是否为主进程
*
* @param
* @return
*/
public boolean isMainProcess() {
return getApplicationContext().getPackageName().equals(getCurrentProcessName());
}