所以即时为应用程序锁定器构建此服务。大多数情况下运行正常。但是当我尝试运行服务来锁定我自己的应用程序(即应用程序锁定器本身)时,会有4-5秒的延迟,然后锁定活动启动。 logcat显示它跳过了600帧并且在主线程上做了太多工作。任何人都可以告诉他我如何解决这个问题或优化此代码
AppActivities
包含当它们位于堆栈顶部时再次启动锁定器时要忽略的活动的名称。将向用户显示锁屏活动。 allowedapp
是用户验证的最后一个应用
public class LockerService extends Service {
String LockedApps[];
String allowedapp = null;
DataBaseHandler handler;
Intent pwdIntent = null;
ActivityManager am;
String[] AppActivities = { "com.packagename.Locker",
"com.packagename.Compare_Pattern",
"com.packagename.Captcha_Verfication",
"com.haibison.android.lockpattern.LockPatternActivity" };
private final static Handler servicehandler = new Handler() {
@Override
public void handleMessage(Message msg) {
}
};
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
handler = new DataBaseHandler(this);
am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
pwdIntent = new Intent(LockerService.this, Locker.class);
pwdIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
private Runnable checkforeground = new Runnable() {
public void run() {
handler.open();
LockedApps = handler.getPackages();
handler.close();
String packname = am.getRunningTasks(1).get(0).topActivity
.getPackageName();
String activityname = am.getRunningTasks(1).get(0).topActivity
.getClassName();
SharedPreferences sp = PreferenceManager
.getDefaultSharedPreferences(LockerService.this);
allowedapp = sp.getString("allowedapp", "anon");
// check if top application is mylocker application
if ((packname.equals("com.packagename"))
&& (allowedapp.equals("com.packagename"))) {
// do nothing
}
// check if top application is mylocker application and prevent relaunching the lockeractivity every 1.5 seconds
else if ((packname.equals("com.packagename"))
&& !(Arrays.asList(AppActivities).contains(activityname))) {
try {
Editor edit = sp.edit();
edit.putString("current_app", packname);
edit.commit();
startActivity(pwdIntent);
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else if ((Arrays.asList(LockedApps).contains(packname))
&& (allowedapp.equals(packname))) {
// do nothing
} else if ((Arrays.asList(LockedApps).contains(packname))) {
Editor edit = sp.edit();
edit.putString("current_app", packname);
edit.commit();
startActivity(pwdIntent);
}
servicehandler.postDelayed(this, 1500); // 1.5 seconds
}
};
@Override
public void onStart(Intent intent, int startId) {
servicehandler.removeCallbacks(checkforeground);
servicehandler.postDelayed(checkforeground, 1500);// 1.5 second
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
servicehandler.removeCallbacks(checkforeground);
stopSelf();
}
}
答案 0 :(得分:0)
主线程上仍然会发生runnable。默认情况下,服务没有自己的线程,它们在UI线程上运行。如果要在服务中执行繁重的处理,则需要使用Thread或AsyncTask,因此UI线程上不会进行处理。
答案 1 :(得分:0)
首先,正如Gabe所提到的,runnable在主Thread上运行。解决帧问题你需要创建另一个新线程来在后台运行你的代码。
在您的服务中尝试初始化executorService
和LcThread
以及布尔running_status
。
running_status变量用于打破线程的while循环,以便在后面停止循环
@Override
public void onStart(Intent intent, int startId) {
running_status = true;
executorService = Executors.newSingleThreadExecutor();
servicehandler.removeCallbacks(LcThread);
LcThread = new LockerThread();
executorService.submit(LcThread);
}
创建以下类
class LockerThread implements Runnable {
@Override
public void run() {
while(running_status){
//copy code from your old Runnable run method here
}
}
}
接下来修改onDestroy
方法
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
if (executorService != null) {
executorService.shutdown();
}
running_status = false;
servicehandler.removeCallbacks(LcThread);
stopSelf();
}
希望这能解决您的问题