1

我设置了一个计时器,AccountActivity.class以确保用户不会按下主页按钮,否则将开始倒计时以注销用户或用户锁定他的屏幕。

但是现在我因为onPause方法而面临一个问题。当我的用户单击调用该getaccounttask()方法的按钮并将我的用户重定向到 时AccountInformationActivity.class,该onPause方法也被激活并且计时器开始倒计时。

是否有任何解决方案可以防止该onPause方法倒计时或我的计时器被取消AccountInformationActivity.class

我试图在我的意图开始之前取消计时器,但仍然不起作用。

我也尝试过使用处理程序,但遇到了同样的问题,我仍在尝试了解 Android 是如何完全工作的,因此非常感谢您的帮助或解决方案。

public class AccountActivity extends AppCompatActivity {

    private Timer timer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_account);
    }

    private class getaccounttask extends AsyncTask<String, Void, String>
    {
      @Override
      protected String doInBackground(String... urlaccount)
      {
        StringBuilder result = new StringBuilder();
        try
        {
            //My Codes
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return result.toString();
      }

      @Override
      protected void onPostExecute(String result)
      {
        Intent intent = new Intent();
        intent.setClass(getApplicationContext(), AccountInformationActivity.class);
        startActivity(intent);
      }
     }

    @Override
    protected void onPause() {
        super.onPause();

        timer = new Timer();
        Log.i("Main", "Invoking logout timer");
        LogOutTimerTask logoutTimeTask = new LogOutTimerTask();
        timer.schedule(logoutTimeTask, 300000); //auto logout in 5 minutes
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (timer != null) {
            timer.cancel();
            Log.i("Main", "cancel timer");
            timer = null;
        }
    }

    private class LogOutTimerTask extends TimerTask {

        @Override
        public void run() {

            //redirect user to login screen
            Intent i = new Intent(AccountActivity.this, MainActivity.class);
            i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            startActivity(i);
            finish();
        }
    }
}
4

3 回答 3

0

进行一些修改onPause()并添加此权限

<uses-permission android:name="android.permission.GET_TASKS" />

    @Override
    protected void onPause() {
        if (isApplicationSentToBackground(this)) {
            // Do what you want to do on detecting Home Key being Pressed
            timer = new Timer();
            Log.i("Main", "Invoking logout timer");
            LogOutTimerTask logoutTimeTask = new LogOutTimerTask();
            timer.schedule(logoutTimeTask, 300000); //auto logout in 5 minutes
            Log.i("Main", "Invoking Home Key pressed");
        }
        super.onPause();

    }

    public boolean isApplicationSentToBackground(final Context context) {
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningTaskInfo> tasks = am.getRunningTasks(1);
        if (!tasks.isEmpty()) {
            ComponentName topActivity = tasks.get(0).topActivity;
            if (!topActivity.getPackageName().equals(context.getPackageName())) {
                return true;
            }
        }
        return false;
    }
于 2016-08-24T04:47:33.533 回答
0

好吧,您选择的实现架构可以得到改进。我稍后会谈到这一点。首先应用此快速修复来修复您的架构。

显然,您想在Timer停止Activity使用主屏幕时开始。但用户也可以Activity使用Intent切换到退出AccountActivity。这个你可以追踪。所以保留一个布尔标志shouldNavigate,最初应该是false。当onResume,它应该设置为false,但当getcounttaskonPostExecute它应该设置为true。因此onPause,如果您要通过getcounttask,shouldNavigate将要出去,true如果是true,请取消您的 Timer,否则,启动您的Timer.

代码:

public class AccountActivity extends AppCompatActivity {

    private Timer timer;
    private volatile boolean shouldNavigate = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_account);
    }

    private class getaccounttask extends AsyncTask<String, Void, String>
    {
      @Override
      protected String doInBackground(String... urlaccount)
      {
        StringBuilder result = new StringBuilder();
        try
        {
            //My Codes
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return result.toString();
      }

      @Override
      protected void onPostExecute(String result)
      {
        shouldNavigate = true;
        Intent intent = new Intent();
        intent.setClass(getApplicationContext(), AccountInformationActivity.class);
        startActivity(intent);
      }
     }

    @Override
    protected void onPause() {
        super.onPause();
        if (!shouldNavigate){
            timer = new Timer();
            Log.i("Main", "Invoking logout timer");
            LogOutTimerTask logoutTimeTask = new LogOutTimerTask();
            timer.schedule(logoutTimeTask, 300000); 
        }else{
            if (timer != null){
                  timer.cancel();
                  timer = null;
            }
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        shouldNavigate = false;
        if (timer != null) {
            timer.cancel();
            Log.i("Main", "cancel timer");
            timer = null;
        }
    }

    private class LogOutTimerTask extends TimerTask {

        @Override
        public void run() {

            //redirect user to login screen
            shouldNavigate = false;
            Intent i = new Intent(AccountActivity.this, MainActivity.class);
            i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            startActivity(i);
            finish();
        }
    }
}

现在更好的方法可能是保留一个Service和一个Singleton类。单例类将是

public Singleton{
    private static Singleton instance = null;
    private Singleton(){
        activityMap = new HashMap<String, Activity>();
    }

    public static Singleton getInstance(){
         if (instance == null) instance = new Singeton();
         return instance;
    }

    public HashMap<String, Activity> activityMap;

}

现在每个活动都会有一个标签(就像它的名字一样),所以每个活动在恢复时都会做

Singleton.getInstance().activityMap.put(tag, this);

onPause什么时候去

Singleton.getInstance().activityMap.remove(tag, this);

因此,当服务发现大小Singleton.getInstance().activityMap为零时,显然前台没有任何活动,因此它启动了一个计时器。当计时器到期时再次检查计数是否仍然为零,如果为零则执行注销。

于 2016-08-24T04:40:32.130 回答
0

我认为您在 Activity 生命周期中混淆了 onPause() 和 onResume() 。 在此处输入图像描述

在您的情况下,您可以将 onPause() 中的操作切换为 onResume()

@Override
    protected void onPause() {
        super.onPause();
        if (timer != null) {
            timer.cancel();
            Log.i("Main", "cancel timer");
            timer = null;
        }

    }

    @Override
    protected void onResume() {
        super.onResume();
        timer = new Timer();
        Log.i("Main", "Invoking logout timer");
        LogOutTimerTask logoutTimeTask = new LogOutTimerTask();
        timer.schedule(logoutTimeTask, 300000); //auto logout in 5 minutes
    }

希望这会有所帮助!

于 2016-08-24T04:29:15.047 回答