2013-04-12 56 views
0

我有奇怪的问题,已经导致我头痛的一周。由asynctask运行的活动不正确地读取sharedpreferences?

我使用改变操作栏中项目标题的切换器,并确保标题设置正确。为了保存这个项目的状态,我使用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> 
+0

很难说出发生了什么,但也许'getPreferences(Context.MODE_PRIVATE);'默认读取错误的文件。你有没有尝试'getSharedPreferences()'与一致的文件名? – Sam

+0

伙计,你是对的!我错误地认为,我在android文档中阅读getPreferences()每个应用程序只使用一个文件,但现在我读它是每个活动。它正确地与getSharedPreferences()一起工作。如果您正确回答我的问题,我会将您的回复标记为已接受。再次感谢! – gadelat

+0

很高兴我可以帮忙,但“伙计”对我来说有点太不正式,“山姆”很好。我已经发布了一个答案。 – Sam

回答

0

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