0
点赞
收藏
分享

微信扫一扫

安卓双进程保活的代码

unadlib 2022-01-28 阅读 70


  首先要声明,双进程保活,不是为了解决被杀之后复活的问题。因为在新版本的安卓上,这个办法已经不灵了(也许有人有更好的办法?)。这里介绍这个双进程保活,是为在电视盒子上的应用。如果进程死了,有的系统会自动启动,有的就不会。而有的应用在电视盒子上必须常在线。

  本文实现方法,与其他介绍的原理一样,代码更加精练。为什么呢?因为使用了继承。

  首先写一个AIDL:

package com.csdn;

interface IKeepAliveServiceConnection
{
String getProcessName();
}

然后写一个父类:

package com.keepalive;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

import com.newayte.nvideo.IKeepAliveServiceConnection;


public abstract class KeepAliveService extends Service
{
private static final String TAG = KeepAliveService.class.getCanonicalName();

private static final String KEEP_ALIVE = "keep-alive";


private KeepAliveBinder mKeepAliveBinder;
private KeepAliveServiceConnection mKeepAliveConnection;

@Override
public void onCreate()
{
super.onCreate();

if (mKeepAliveBinder == null)
{
mKeepAliveBinder = new KeepAliveBinder();
mKeepAliveConnection = new KeepAliveServiceConnection();
}
}

@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
bindService(getConnectionIntent(), mKeepAliveConnection, Context.BIND_IMPORTANT);

Log.d(TAG, "onStartCommand()");
/*PendingIntent contentIntent = PendingIntent.getService(this, 0, intent, 0);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setTicker("CSDN")
.setContentIntent(contentIntent)
.setContentTitle("TITLE")
.setAutoCancel(true)
.setContentText("CONTENT")
.setWhen( System.currentTimeMillis());

//把service设置为前台运行
startForeground(startId, builder.build());*/

return START_STICKY;
}

@Override
public IBinder onBind(Intent intent)
{
//子类如果跟其他进程绑定时,从父类得到的binder不为空,说明是从保活服务启动的。
Log.d(TAG, KEEP_ALIVE+"="+intent.getBooleanExtra(KEEP_ALIVE, false)+", "+intent);
if (intent.getBooleanExtra(KEEP_ALIVE, false))
{
return mKeepAliveBinder;
}
return null;
}

private Intent getConnectionIntent()
{
Intent intent = new Intent(KeepAliveService.this, getPeerService());
intent.putExtra(KEEP_ALIVE, true);
return intent;
}

class KeepAliveBinder extends IKeepAliveServiceConnection.Stub
{
@Override
public String getProcessName() throws RemoteException
{
return getServiceName();
}
}

class KeepAliveServiceConnection implements ServiceConnection
{

@Override
public void onServiceConnected(ComponentName name, IBinder service)
{
Log.d(TAG, getPeerService().getCanonicalName()+"建立连接成功!");
}

@Override
public void onServiceDisconnected(ComponentName name)
{
Log.d(TAG, getPeerService().getCanonicalName()+"服务进程已死。重新启动并建立链接。");
//启动被干掉的
KeepAliveService.this.startService(getConnectionIntent());
KeepAliveService.this.bindService(getConnectionIntent(), mKeepAliveConnection, Context.BIND_IMPORTANT);
}

}

/**
* 这两个并不是必要的。
* 考虑到子类,还是要有点代码的。
*
* @return
*/
protected abstract String getServiceName();

protected abstract Class<?> getPeerService();

}

子类服务助手(怎么样?使用了继承,极为简单吧):

package com.keepalive;

public class AssistantServiceTv extends KeepAliveService
{

@Override
protected String getServiceName()
{
return AssistantServiceTv.class.getCanonicalName();
}

@Override
protected Class<?> getPeerService()
{
return NetworkServiceTv.class;
}

}

主服务(注意onBind()的代码):

package com.keepalive;

public class NetworkServiceTv extends KeepAliveService
{
@Override
public IBinder onBind(Intent intent)
{
Log.d(TAG, "service onBind="+intent);
IBinder binder = super.onBind(intent);
if (null != binder)
{
return binder;
}
return mBinder;
}

@Override
protected String getServiceName()
{
return NetworkServiceTv.class.getCanonicalName();
}

@Override
protected Class<?> getPeerService()
{
return AssistantServiceTv.class;
}

}


在NetworkServiceTv中负责联网。这样即使其中一个进程因错误崩溃,也可以被启动再次联网。



举报

相关推荐

0 条评论