我们写的程序在手机上面运行的好好的,一旦打开应用过多,手机内存不够的时候,系统首先会 kill 掉我们的程序。kill 在后台运行的service。
我查了很多方法,什么提高级别,什么把service设置成前台组件,都不管用。
后来想到一个方法,屡试不爽。
原理:activity 和 service 是运行在同一个线程中的,只要不让这个线程无操作太久就行。也就是每隔一段时间就运行一下这个UI线程。优化:如果手机当前打开的activity是自身,那就忽略。
代码:
package com.example.runalways;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//开启service
Intent intent = new Intent();
intent.setClass(this, MyService.class);
this.startService(intent);
}
}
package com.example.runalways;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
public class MyService extends Service {
private RunAlways runAlways;
@Override
public void onCreate() {
//只要在service中new一个对象,然后start方法
runAlways = new RunAlways(this);
runAlways.start();
}
@Override
public void onDestroy() {
//最后在onDestory中close就行
runAlways.close();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.runalways"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<!-- 加入权限,获取当前正在运行的activity用 -->
<uses-permission android:name="android.permission.GET_TASKS"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.runalways.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- 注册service -->
<service android:name="com.example.runalways.MyService"></service>
</application>
</manifest>
已封装好的类:直接用就行
package com.example.runalways;
import android.app.ActivityManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
/**
* 这是一个封装好的类,
* 要实现不被系统 kill 掉的service,
* 只要在service中new一个对象,然后start方法,最后在onDestory中close就行
* 注意:要加入权限 <uses-permission android:name="android.permission.GET_TASKS"/>
* @author LinZhiquan
*
*/
public class RunAlways {
private Context context;
private BroadcastReceiver myReceiver;
/** 当service关闭的时候停止线程 */
private boolean flag_runnable = true;
public RunAlways(Context context) {
this.context = context;
myReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
}
/**
* 开启线程
*/
public void start() {
// 注册广播接收器,当当前运行的程序不是自身,则让service运行一下
IntentFilter filter = new IntentFilter();
filter.addAction("com.example.runalways.notSelf");
context.registerReceiver(myReceiver, filter);
// 开启线程,隔一段时间就判断一下当前运行的程序是不是自身,如果不是,则发送广播
new Thread(new MyRunnable()).start();
}
/**
* 关闭,取消注册接收器以及停止线程
*/
public void close() {
// 记得取消广播注册,和关闭线程
context.unregisterReceiver(myReceiver);
this.flag_runnable = false;
}
private class MyRunnable implements Runnable {
@Override
public void run() {
while (flag_runnable) {
try {
Thread.sleep(3000);
// 获取当前运行的Activity
ActivityManager am = (ActivityManager) context
.getSystemService(Context.ACTIVITY_SERVICE);
ComponentName cn = am.getRunningTasks(1).get(0).topActivity;
String pkgName = cn.getPackageName();
if (!pkgName.equals(context.getPackageName())) {
Intent intent = new Intent();
intent.setAction("com.example.runalways.notSelf");
context.sendBroadcast(intent);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}