打开活动时,Android AsyncTask会重新运行

时间:2014-10-29 11:19:25

标签: android android-asynctask

在我的应用中,用户必须登录。

  • 他们在登录页面上打开应用程序
  • 他们输入电子邮件/密码并点击登录
  • 打开一个具有旋转圆圈并且正在运行AsyncTask的LoadingScreenActivity,该AsyncTask将转到我的数据库并检索所有用户信息

AsyncTask完成后,它启动了一个启动MainPageActivity的意图。

目前有两个问题:

  1. 如果用户登录然后在应用程序加载时进入主屏幕,MainPageActivity将在准备就绪后立即打开(在现有主页的顶部),即使应用程序已最小化
  2. 如果用户登录然后在应用加载时转到主屏幕,然后返回到加载屏幕,AsyncTask将完成两次
  3. 问题1.目前,我在LoadingScreenActivity中的onPostExecute()方法如下所示:

        @Override
        public void onPostExecute() {
            //open the main page  
            Intent mainPage = new Intent(getApplicationContext(), MainPageActivity.class);                             
            mainPage.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            mainPage.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK );
            startActivity(mainPage);
        }
    

    如果主页面活动应该打开,有没有办法在这种方法中检测到?

    对于问题2.我已经完成了一个完整的路障,有没有办法检测活动是否只是重新打开而不是第一次启动?我非常感谢有关这方面的任何提示,我对android很新,所以我甚至不相信Async任务是这样做的。

    感谢您的时间

    LoadingScreenActivity.java

        public class LoadingScreenActivity extends Activity implements TaskFragment.TaskCallbacks {
    
    private static final String TAG_TASK_FRAGMENT = "task_fragment";
    private TaskFragment mTaskFragment;
    
    @Override 
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
    
        FragmentManager fm = getFragmentManager();
        mTaskFragment = (TaskFragment) fm.findFragmentByTag(TAG_TASK_FRAGMENT);
    
        // If the Fragment is non-null, then it is currently being
        // retained across a configuration change.
        if (mTaskFragment == null) {
          mTaskFragment = new TaskFragment();
          fm.beginTransaction().add(mTaskFragment, TAG_TASK_FRAGMENT).commit();
        }
    
        setContentView(R.layout.loading_screen);
        ActionBar actionBar = getActionBar();
        actionBar.hide();
        TextView title = (TextView) findViewById(R.id.loading_title);  
        TextView progress = (TextView) findViewById(R.id.loading_progress);  
    
        title.setText(R.string.app_name);
        progress.setText("Loading your info");
    }
    
    
    
    @Override
    public Context onPreExecute() { 
    
        return getApplicationContext();
    }
    
    @Override
    public void onProgressUpdate(int percent) {   
    }
    
    @Override
    public void onCancelled() {
        Intent login = new Intent(getApplicationContext(), LoginActivity.class);
        login.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(login);
        finish();
    }
    
    @Override
    public void onPostExecute() {
        //open the main page  
        Intent mainPage = new Intent(getApplicationContext(), MainPageActivity.class);                             
        mainPage.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        mainPage.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK );
        startActivity(mainPage);
    }
    
    }
    

    和TaskFragment.java

    public class TaskFragment extends Fragment {
    
    
      static interface TaskCallbacks {
        Context onPreExecute();
        void onProgressUpdate(int percent);
        void onCancelled();
        void onPostExecute();
      }
    
      private TaskCallbacks mCallbacks;
      private DummyTask mTask;
    
    
      @Override
      public void onAttach(Activity activity) {
        super.onAttach(activity);
        mCallbacks = (TaskCallbacks) activity;
    
    
      }
    
    
      @Override
      public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        // Retain this fragment across configuration changes.
        setRetainInstance(true);
    
        // Create and execute the background task.
        mTask = new DummyTask();
        mTask.execute();
      }
    
    
      @Override
      public void onDetach() {
        super.onDetach();
        mCallbacks = null;
      }
    
    
      private class DummyTask extends AsyncTask<Void, Integer, Void> {
      Context context;
      boolean running = true;
    
    @Override
    protected void onPreExecute() {
      if (mCallbacks != null) {
        context = mCallbacks.onPreExecute();
      }
    }
    
    
    @Override
    protected Void doInBackground(Void... ignore) {
        //Get the current thread's token  
        synchronized (this)  
        {
            if(running){
                DatabaseHandler dbHandler = new DatabaseHandler(context);
                dbHandler.populateSQLiteDatabase();
            }
    
        }  
    
        return null;
    }
    
    @Override
    protected void onProgressUpdate(Integer... percent) {
      if (mCallbacks != null) {
        mCallbacks.onProgressUpdate(percent[0]);
      }
    }
    
    @Override
    protected void onCancelled() {
      if (mCallbacks != null) {
        mCallbacks.onCancelled();
      }
    }
    
    @Override
    protected void onPostExecute(Void ignore) {
      if (mCallbacks != null) {
        mCallbacks.onPostExecute();
      }
    }
    
    
      }
    }
    

2 个答案:

答案 0 :(得分:0)

在清单中的活动中添加android:configChanges="keyboardHidden|orientation|screenSize"  并在活动中实施此

@Override
    public void onConfigurationChanged(Configuration newConfig) {
};

答案 1 :(得分:0)

我很害怕,我真的不明白你的第一个问题。 关于第二个,根据您的最低API级别,有几种方法。从API 14开始,您可以在Android应用程序中注册ActivityLifecycle Callbacks。为此,我建议:

  1. 使用自定义
  2. 继承Android应用程序
  3. 替换清单中的Android应用程序
  4. 在自定义应用程序中将自身注册为活动生命周期监听器
  5. 在抽象方法中,您获得当前应用活动的实例(可能在字符串中安全object.name()
  6. 根据您的处理方式,您可以安全地使用布尔值或任何识别行为的内容
  7. 通过投射(MyCustomApplication)getApplication() 可以访问自定义应用程序中的
  8. 方法

    Heres一个片段:

    package com.example.preferencestest;
    
    import android.app.Activity;
    import android.app.Application;
    import android.app.Application.ActivityLifecycleCallbacks;
    import android.os.Bundle;
    
    public class MyCustomApplication extends Application implements ActivityLifecycleCallbacks {
        private String storedActivity;
        private Boolean doOrNot = false;
    
        public MyCustomApplication() {}
        public Boolean getDoOrNot() { return doOrNot;}
        public void setDoOrNot(Boolean doOrNot) { this.doOrNot = doOrNot; }
    
        @Override
        public void onCreate() {
            super.onCreate();
            registerActivityLifecycleCallbacks(this);
        }
    
        // these two are the most important ones since they will be fired everytime
        @Override
        public void onActivityResumed(Activity activity) {
            if (activity.getClass().getName().equals(storedActivity)) {
                doOrNot = true;
            }
        }
        @Override
        public void onActivityPaused(Activity activity) {
            storedActivity = activity.getClass().getName();
        }
    
    
        @Override
        public void onActivityCreated(Activity activity, Bundle savedInstanceState) { }
        @Override
        public void onActivityStarted(Activity activity) { }
        @Override
        public void onActivityStopped(Activity activity) { }
        @Override
        public void onActivitySaveInstanceState(Activity activity, Bundle outState) { }
        @Override
        public void onActivityDestroyed(Activity activity) { }
    }
    
    在你的Manifest中你必须声明这个新的Applicationclass:

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.preferencestest"
        android:versionCode="1"
        android:versionName="1.0" >
    
        <uses-sdk
            android:minSdkVersion="16"
            android:targetSdkVersion="21" />
    
        <application
            android:name="com.example.preferencestest.MyCustomApplication"
    {...}
    

    然后在你的活动中你可以这样做:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Boolean whatToDo = ((MyCustomApplication)getApplication()).getDoOrNot();
    }
    

    使用onConfigurationChanged有一些缺点。有几个操作(将设备放置在底座,转动显示器等),重新启动活动。您应该使用

    保存活动的当前状态
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
    }
    @Override
    protected void onRestoreInstanceState(Bundle state) {
        super.onRestoreInstanceState(state);
    }