如何像QQ一樣進(jìn)程不被系統(tǒng)殺死

如何像QQ一樣進(jìn)程不被系統(tǒng)殺死

2018-01-29?香沙小熊?代碼集中營(yíng)

點(diǎn)擊上方“代碼集中營(yíng)”,選擇“置頂公眾號(hào)”

優(yōu)秀文章,第一時(shí)間送達(dá)!

今天介紹一個(gè)android的Service,他是一個(gè)后臺(tái)服務(wù),專門(mén)用來(lái)處理常駐后臺(tái)的工作組件。我們用的即時(shí)通訊,service來(lái)做常駐后臺(tái)

進(jìn)程優(yōu)先級(jí)

進(jìn)程的重要性優(yōu)先級(jí):

1. 前臺(tái)進(jìn)程:Foreground process

用戶正在交互的Activity(onResume()

當(dāng)某個(gè)Service綁定正在交互的Activity

被主動(dòng)調(diào)用為前臺(tái)的Service(startForeground())

組件正在執(zhí)行生命周期的回調(diào)((onCreate() /onStart()/onDestory())

BroadcastReceiver 正在執(zhí)行onReceive();

2.可見(jiàn)進(jìn)程:Visible process

我們的Activity處在onPause() (沒(méi)有進(jìn)入onStop())

綁定到前臺(tái)Activity的Service

3.服務(wù)進(jìn)程:Service process

簡(jiǎn)單的startservice()啟動(dòng)

4.后臺(tái)進(jìn)程:Background process

對(duì)用戶沒(méi)有直接影響的進(jìn)程-----Activity處于onStop()的時(shí)候

5.空進(jìn)程 ? ?:Empty process

不含有任何的活動(dòng)的組件。(android設(shè)計(jì)的,為了第二次啟動(dòng)更快,采取了一個(gè)權(quán)衡)

進(jìn)程越往后越容易被系統(tǒng)殺死

如何不被系統(tǒng)殺死

我們要如何提升進(jìn)程的優(yōu)先級(jí)(盡量做到不輕易被系統(tǒng)殺死),提供以下七個(gè)方案

1. 模仿QQ采取在鎖屏的時(shí)候啟動(dòng)1個(gè)像素的Activity。

背景:當(dāng)手機(jī)鎖屏的時(shí)候什么都干死了,為了省電。

監(jiān)聽(tīng)鎖屏廣播,鎖了---啟動(dòng)這個(gè)1像素Activity。

監(jiān)聽(tīng)鎖屏的, ?開(kāi)啟---結(jié)束掉這個(gè)1像素Activity。

要監(jiān)聽(tīng)鎖屏的廣播---動(dòng)態(tài)注冊(cè)。

關(guān)鍵代碼:

publicclassKeepLiveActivityManager{

privatestaticKeepLiveActivityManager instance;

privateContext context;

privateWeakReference activityInstance;

publicstaticKeepLiveActivityManagergetInstance(Context context){

if(instance==null){

instance =newKeepLiveActivityManager(context.getApplicationContext());

}

returninstance;

}

privateKeepLiveActivityManager(Context context){

this.context = context;

}

publicvoidsetKeepLiveActivity(Activity activity){

activityInstance =newWeakReference(activity);

}

publicvoidstartKeepLiveActivity(){

Intent intent =newIntent(context, KeepLiveActivity.class);

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

context.startActivity(intent);

}

publicvoidfinishKeepLiveActivity(){

if(activityInstance!=null&&activityInstance.get()!=null){

Activity activity = activityInstance.get();

activity.finish();

} ? ?}

}

源碼地址:https://github.com/kpioneer123/KeepLiveProcess

2. 大型App運(yùn)營(yíng)商和手機(jī)廠商可能有合作關(guān)系---白名單

3. 雙進(jìn)程守護(hù)

一個(gè)進(jìn)程被殺死,另外一個(gè)進(jìn)程又被他啟動(dòng),相互監(jiān)聽(tīng)啟動(dòng)。

A<---->B

殺進(jìn)程是一個(gè)一個(gè)殺的,本質(zhì)是和殺進(jìn)程時(shí)間賽跑。

關(guān)鍵代碼:

publicclassLocalServiceextendsService{

publicstaticfinalString ACTION_LOCAL_SERVICE ="com.haocai.app.keepliveprocess.LocalService";

privatestaticfinalString TAG ="LocalService";

privateMyServiceConnection conn;

privateMyBinder binder;

privateIntent testIntent;

@Override

publicvoidonCreate(){

// TODO Auto-generated method stub

super.onCreate();

if(binder ==null){

binder =newMyBinder();

}

conn =newMyServiceConnection();

}

@Nullable

@Override

publicIBinderonBind(Intent intent){

returnbinder;

}

@Override

publicvoidonDestroy(){

super.onDestroy();

if(testIntent!=null){

stopService(testIntent);

}

//unbindService(conn);

}

//啟動(dòng)前臺(tái)進(jìn)程 增加重要性優(yōu)先級(jí)

@Override

publicintonStartCommand(Intent intent,intflags,intstartId){

LocalService.this.bindService(newIntent(LocalService.this, RemoteService.class), conn, Context.BIND_IMPORTANT);

PendingIntent contentIntent = PendingIntent.getService(this,0, intent,0);

NotificationCompat.Builder builder =newNotificationCompat.Builder(this);

builder.setTicker("360")

.setContentIntent(contentIntent)

.setContentTitle("我是360,我怕誰(shuí)!")

.setAutoCancel(true)

.setContentText("hehehe")

.setWhen( System.currentTimeMillis());

//把service設(shè)置為前臺(tái)運(yùn)行,避免手機(jī)系統(tǒng)自動(dòng)殺掉改服務(wù)。

startForeground(startId, builder.build());

returnSTART_STICKY;

}

classMyBinderextendsRemoteConnection.Stub{

@Override

publicStringgetProcessName()throwsRemoteException{

// TODO Auto-generated method stub

return"LocalService";

}

}

classMyServiceConnectionimplementsServiceConnection{

@Override

publicvoidonServiceConnected(ComponentName name, IBinder service){

Log.i(TAG,"建立連接成功!");

}

@Override

publicvoidonServiceDisconnected(ComponentName name){

Log.i(TAG,"本地服務(wù)被干掉了~~~~~斷開(kāi)連接!");

Toast.makeText(LocalService.this,"斷開(kāi)連接", Toast.LENGTH_SHORT).show();

//啟動(dòng)被干掉的

testIntent =newIntent();

//自定義的Service的action

testIntent.setAction(RemoteService.ACTION_REMOTE_SERVICE);

//自定義Service的包名

testIntent.setPackage(getPackageName());

Log.i("999", getPackageName() +"");

startService(testIntent);

LocalService.this.bindService(newIntent(LocalService.this, RemoteService.class), conn, Context.BIND_IMPORTANT);

}

}

}

源碼地址:https://github.com/kpioneer123/KeepLiveProcess2

4. JobScheduler

把任務(wù)加到系統(tǒng)調(diào)度隊(duì)列中,當(dāng)?shù)竭_(dá)任務(wù)窗口期的時(shí)候就會(huì)執(zhí)行,我們可以在這個(gè)任務(wù)里面啟動(dòng)我們的進(jìn)程。這樣可以做到將近殺不死的進(jìn)程。

@SuppressLint("NewApi")

publicclassJobHandleServiceextendsJobService{

publicstaticfinalString ACTION_JOB_HANDLE_SERVICE ="com.haocai.app.keepliveprocess.JobHandleService";

privateintkJobId =0;

@Override

publicvoidonCreate(){

super.onCreate();

Log.i("INFO","jobService create");

}

@Override

publicintonStartCommand(Intent intent,intflags,intstartId){

Log.i("INFO","jobService start");

scheduleJob(getJobInfo());

returnSTART_NOT_STICKY;

}

@Override

publicvoidonDestroy(){

// TODO Auto-generated method stub

super.onDestroy();

}

@Override

publicbooleanonStartJob(JobParameters params){

// TODO Auto-generated method stub

Log.i("INFO","job start");

// ? ? ?scheduleJob(getJobInfo());

booleanisLocalServiceWork = isServiceWork(this, LocalService.ACTION_LOCAL_SERVICE);

booleanisRemoteServiceWork = isServiceWork(this, RemoteService.ACTION_REMOTE_SERVICE);

// ? ? ?Log.i("INFO", "localSericeWork:"+isLocalServiceWork);

// ? ? ?Log.i("INFO", "remoteSericeWork:"+isRemoteServiceWork);

if(!isLocalServiceWork||

!isRemoteServiceWork){

//this.startService(new Intent(this,LocalService.class));

startLocalService();

startRemoteService();

//this.startService(new Intent(this,RemoteService.class));

Toast.makeText(this,"process start", Toast.LENGTH_SHORT).show();

}

returntrue;

}

privatevoidstartLocalService(){

Intent ?testIntent =newIntent();

//自定義的Service的action

testIntent.setAction(LocalService.ACTION_LOCAL_SERVICE);

//自定義Service的包名

testIntent.setPackage(getPackageName());

Log.i("999",getPackageName()+"");

startService(testIntent);

}

privatevoidstartRemoteService(){

Intent testIntent =newIntent();

//自定義的Service的action

testIntent.setAction(RemoteService.ACTION_REMOTE_SERVICE);

//自定義Service的包名

testIntent.setPackage(getPackageName());

Log.i("999", getPackageName() +"");

startService(testIntent);

}

@Override

publicbooleanonStopJob(JobParameters params){

Log.i("INFO","job stop");

// ? ? ?Toast.makeText(this, "process stop", Toast.LENGTH_SHORT).show();

scheduleJob(getJobInfo());

returntrue;

}

/** Send job to the JobScheduler. */

publicvoidscheduleJob(JobInfo t){

Log.i("INFO","Scheduling job");

JobScheduler tm =

(JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);

tm.schedule(t);

}

publicJobInfogetJobInfo(){

JobInfo.Builder builder =newJobInfo.Builder(kJobId++,newComponentName(this, JobHandleService.class));

builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);

builder.setPersisted(true);

builder.setRequiresCharging(false);

builder.setRequiresDeviceIdle(false);

builder.setPeriodic(10);//間隔時(shí)間--周期

returnbuilder.build();

}

/**

* 判斷某個(gè)服務(wù)是否正在運(yùn)行的方法

*

*@parammContext

*@paramserviceName

* ? ? ? ? ? ?是包名+服務(wù)的類名(例如:net.loonggg.testbackstage.TestService)

*@returntrue代表正在運(yùn)行,false代表服務(wù)沒(méi)有正在運(yùn)行

*/

publicbooleanisServiceWork(Context mContext, String serviceName){

booleanisWork =false;

ActivityManager myAM = (ActivityManager) mContext

.getSystemService(Context.ACTIVITY_SERVICE);

List myList = myAM.getRunningServices(100);

if(myList.size() <=0) {

returnfalse;

}

for(inti =0; i < myList.size(); i++) {

String mName = myList.get(i).service.getClassName().toString();

if(mName.equals(serviceName)) {

isWork =true;

break;

}

}

returnisWork;

}

}

5. 監(jiān)聽(tīng)QQ,微信,系統(tǒng)應(yīng)用,友盟,小米推送等等的廣播,然后把自己?jiǎn)?dòng)了。

6. 利用賬號(hào)同步機(jī)制喚醒我們的進(jìn)程AccountManager

7. NDK來(lái)解決,Native進(jìn)程來(lái)實(shí)現(xiàn)雙進(jìn)程守護(hù)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容