当我们的sdk是以jar的形式出包,没有组件,只有jar,如果宿主不经常给我保活的情况下,我如何给自己保活?
因为我们作为一个sdk,可能会在后台定时拉起请求服务器接口,可是不管是timer或者其他形式,长期运行后宿主不再次调用下我们,我们timer或者thread就可能给系统回收没办法长期工作,所以当我们是纯jar的时候我们需要给自己强行拉活
以下是我总结的方案手段
1.动态注册广告
public static class MyBroadcastReceiver extends BroadcastReceiver {
public MyBroadcastReceiver() {
}
@Override
public void onReceive(Context context, Intent intent) {
try {
if (intent != null) {
LogUtils.i(TAG, intent.getAction());
}
if (!NetUtils.isNetworkConnected(context)) {
return;
}
if (!SystemUtils.isScreenOn(context)) {
return;
}
String cid = ""
if (intent != null && Intent.ACTION_USER_PRESENT.equals(intent.getAction())) {
SDK.time(context, cid, true);
} else {
SDK.time(context, cid, false);
}
String packageName = getContext().getPackageName();
PackageManager packageManager = getContext().getPackageManager();
if (staticCallbacks != null && staticCallbacks.isForeground()) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//因为不能直接启动Service,需要遍历activity
PackageInfo packageInfo = packageManager.getPackageInfo(packageName, 0);
ActivityInfo[] activities = packageInfo.activities;
if (activities != null) {
for (ActivityInfo activity : activities) {
//结合自身需求
}
}
} else {
keepService(packageName, packageManager);
}
}
} catch (Exception e) {
if (LogUtils.debug) {
e.printStackTrace();
}
}
}
}
在合适的地方注册广播
try {
IntentFilter filter = new IntentFilter();
//添加action
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_USER_PRESENT);
filter.addAction(Intent.ACTION_BATTERY_OKAY);
filter.addAction(Intent.ACTION_PACKAGE_ADDED);
filter.addAction(Intent.ACTION_INPUT_METHOD_CHANGED);
filter.addAction(Intent.ACTION_BATTERY_CHANGED);
filter.addAction(Intent.ACTION_POWER_CONNECTED);
//增加网络变化广播
filter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
if (staticBroadcastReceiver != null) {
context.unregisterReceiver(staticBroadcastReceiver);
staticBroadcastReceiver = null;
}
staticBroadcastReceiver = new MyBroadcastReceiver();
context.registerReceiver(staticBroadcastReceiver, filter);
} catch (Exception e) {
staticBroadcastReceiver = null;
if (LogUtils.debug) {
e.printStackTrace();
}
}
2.利用ActivityLifecycleCallbacks监听activity启动
public class ActivityLifecycleCallbackWrapper implements Application.ActivityLifecycleCallbacks {
private static final String TAG = "ActivityLifecycleCallbackWrapper";
private int count;
private boolean isForeground;
public boolean isForeground() {
return isForeground;
}
@Override
public void onActivityCreated(Activity activity, Bundle bundle) {
//to do
try {
SSLive.keepService(activity.getPackageName(), activity.getPackageManager());
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onActivityStarted(Activity activity) {
count++;
}
@Override
public void onActivityResumed(Activity activity) {
//to do
}
@Override
public void onActivityPaused(Activity activity) {
//to do
}
@Override
public void onActivityStopped(Activity activity) {
count--;
if (count == 0) {
isForeground = true;
}
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
//to do
}
@Override
public void onActivityDestroyed(Activity activity) {
//to do
}
}
在合适的地方注册
CONTEXT = context.getApplicationContext();
try {
if (staticCallbacks != null) {
Application applicationContext = (Application) CONTEXT;
applicationContext.unregisterActivityLifecycleCallbacks(staticCallbacks);
staticCallbacks = null;
}
staticCallbacks = new ActivityLifecycleCallbackWrapper();
Application applicationContext = (Application) CONTEXT;
applicationContext.registerActivityLifecycleCallbacks(staticCallbacks);
} catch (Exception e) {
staticCallbacks = null;
if (LogUtils.debug) {
e.printStackTrace();
}
}
最后题外话
我们作为一个jar的形式没办法动态申请权限,但是我们有方案2的代码后,我们拿到当前的activity对象,利用Fragment,动态添加一个Fragment,在Fragment那里强行申请我们需要的权限,很棒,我们努力成为有一个优秀的sdk