asynctask运行的活动是否错误地读取了共享偏好?

时间:2013-04-12 22:17:13

标签: android android-asynctask sharedpreferences

我有一些奇怪的问题导致我一周头疼。

我使用某种切换器来改变操作栏中项目的标题,并确保标题设置正确。为了保存这个项目的状态,我使用共享偏好。

在应用程序的其他部分,我使用asynctask。问题是当asynctask正在运行时,BaseActivity会读取错误的操作栏设置值,因此在asynctask完成之前它的标题不正确。

我为你准备了这个bug的例子。奇怪的是,如果我在方法onPostExecute中将活动从ExtendActivity更改为RefreshActivity,那么它确实会读取并设置正确的标题。当然,我不能在实际应用中这样做。

BaseActivity:

    public class BaseActivity extends Activity {

    public boolean menub;
    public Menu menu;
    public SharedPreferences pref;

    @Override 
    public void onCreate(Bundle savedInstanceState) {
         this.pref = this.getPreferences(Context.MODE_PRIVATE);
         super.onCreate(savedInstanceState);
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu, menu);
        this.menu = menu;
        this.menub = pref.getBoolean("menub", true);
        _switch(false);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.menu_refresh:
                startActivity(new Intent(this, RefreshActivity.class));
                return true;
            case R.id.menu_test:
                _switch(true);
            default:
                return false;
        }
    }
    public void _switch(boolean swtch) {
        String n;
        if (swtch) {
            SharedPreferences.Editor e = pref.edit();
            if (menub) {
                e.putBoolean("menub",false);
                n="A";
            }
            else {
                e.putBoolean("menub", true);
                n="B";
            }
            e.apply();
        }
        else {
            if (menub) n="B";
            else n="A";
        }
        menu.findItem(R.id.menu_test).setTitle(n);      
    }
}

RefreshActivity:

public class RefreshActivity extends BaseActivity {

    protected ImageLoader imageLoader = ImageLoader.getInstance();
    public Activity thisActivity;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        thisActivity=this;  
        Bundle b = getIntent().getExtras();
        if (b==null) {
            load();
        }
        else {
            if (b.containsKey("loaded")) {
                new _async().execute();
            }
        }
    }
    private class _async extends AsyncTask<Object, Void, Integer> {
        @Override
        protected Integer doInBackground(Object... params) {
            try {Thread.sleep(2000);} catch (InterruptedException e) {}
            return 1;
        }
        @Override
        protected void onPostExecute(Integer response) {
            Intent intent = new Intent(thisActivity,ExtendActivity.class);
            intent.putExtra("id_folder", 0);
            startActivity(intent); 
            thisActivity.finish();
        }
     }
    public void load() {
        Intent intent = new Intent(this,RefreshActivity.class);
        intent.putExtra("loaded",true);
        startActivity(intent); 
        ((Activity) this).finish();
    }
}

ExtendActivity:

public class ExtendActivity extends RefreshActivity {

}

menu.xml文件:

    <?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
    <item
        android:id="@+id/menu_refresh"
        android:title="Refresh"
        android:showAsAction="ifRoom|withText"/>

        <item android:id="@+id/menu_test"
              android:title="A"
              android:showAsAction="ifRoom|withText" />
</menu>

1 个答案:

答案 0 :(得分:0)

getPreferences()可能很棘手,它假设您只希望一个Activity使用您的SharedPreferences文件。 (如果您需要详细信息,请查看source code。)我建议使用getSharedPreferences()代替一致的文件名。这样,ExtendActivity,RefreshActivity和BaseActivity都将从同一个文件中读取。