【问题标题】:Application skipping 600 frames应用程序跳过 600 帧
【发布时间】:2015-02-19 23:00:06
【问题描述】:

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

【问题讨论】:

    标签: android multithreading performance optimization service


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      首先,正如 Gabe 所提到的,一个可运行对象在主线程上运行。要解决框架问题,您需要创建另一个新线程来在后台运行您的代码。

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

      希望这能解决您的问题

      【讨论】:

      • 谢谢你..似乎有点滞后..但它明显比以前少了
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-06-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多