应用程序跳过600帧

时间:2014-12-21 18:53:17

标签: android multithreading performance optimization service

所以即时为应用程序锁定器构建此服务。大多数情况下运行正常。但是当我尝试运行服务来锁定我自己的应用程序(即应用程序锁定器本身)时,会有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();
}
}

2 个答案:

答案 0 :(得分:0)

主线程上仍然会发生runnable。默认情况下,服务没有自己的线程,它们在UI线程上运行。如果要在服务中执行繁重的处理,则需要使用Thread或AsyncTask,因此UI线程上不会进行处理。

答案 1 :(得分:0)

首先,正如Gabe所提到的,runnable在主Thread上运行。解决帧问题你需要创建另一个新线程来在后台运行你的代码。

在您的服务中尝试初始化executorServiceLcThread以及布尔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();
}

希望这能解决您的问题