【问题标题】:how to stop app executing until AsyncTask has populated SharedPreferences如何在 AsyncTask 填充 SharedPreferences 之前停止应用程序执行
【发布时间】:2012-10-23 11:08:01
【问题描述】:

我有一个调用 web 服务并检索 contentValue 对象的应用程序。该对象填充了最终作为 SharedPreferences 存储的字符串字符串值。我已经使用 AsyncTask 进行 web 服务调用,以免阻塞 UI 线程。 Web 服务会填充 CV 对象。

问题出在我尝试使用共享首选项中的值时。共享首选项对象为空。应用程序在 AsyncTask 实例化并填充它之前尝试使用此对象。如何让应用程序等到 AsyncTask 完成?

CompID 是作为参数传递给 Web 服务的字符串。如果第一次安装应用程序时此变量为空,我会显示一个对话框,要求用户输入 compID。

if(nfcscannerapplication.getCompId() == null || 
                                   nfcscannerapplication.getCompId().trim().equalsIgnoreCase("null")){ 
            Log.e(TAG, "compid null***********");
            showPasswordDialogBox();

        }

ShowPasswordDialogBox(未恰当命名)获取 compID 并将其传递给 asyncCompOpt()。

public void asyncCompOpt(){

        String[] paramsCompOpt = new String[]{nfcscannerapplication.getCompId()};
        AsyncGetCompanyOptions agco = new AsyncGetCompanyOptions();
        agco.execute(paramsCompOpt);

    }

asyncCompOpt 调用 AsyncTask。

private class AsyncGetCompanyOptions extends AsyncTask<String, Void, ContentValues> {

    ProgressDialog progressDialog;

    @Override
    protected void onPreExecute()
    {
        progressDialog = ProgressDialog.show(EntryActivity.this, 
                "Connecting to Server"," Getting your company's options...", true);


    };      


    @Override
    protected ContentValues doInBackground(String... params) {

        ContentValues cv = null;

        try {
            Log.e(TAG, "inside doInBackground");
            cv = loginWebservice.getCompanyOptionsAndPhonenumbers(nfcscannerapplication.getCompId());

            if(cv == null){
                Log.e(TAG, "cv is null");
            }else{
                Log.e(TAG, "cv is not null");
            }




        } catch (Exception e) {
           e.printStackTrace();
        }
        return cv; 


    }

    @Override
    protected void onPostExecute(ContentValues result)
    {
        super.onPostExecute(result);
        if(progressDialog != null)
        progressDialog.dismiss();

        String tagTouchInterval = (String) result.get("10"); 
        Log.e(TAG, "tagTouchInterval in onpostexecute = " + tagTouchInterval);
        String savePassword = (String) result.get("20");
        String allowChangeUser = (String) result.get("30");
        String displayRotaDetails = (String) result.get("40");
        String displayClientPhoneNumber = (String) result.get("50");
        String displayClientKeysafe = (String) result.get("60");
        String displayDoubleupCarer = (String) result.get("70");
        String displayContacts = (String) result.get("80");
        String autoLogout = (String) result.get("90");
        String displayNotesDisplayNotes = (String) result.get("100");
        String displayMeds = (String) result.get("110");
        String rotaLogout = (String) result.get("120");
        String displayActualTime = (String) result.get("130");
        String qrcodeEnabled = (String) result.get("140");
        String manualInput = (String) result.get("150");
        String rotasOnly = (String) result.get("160");

        appSharedPrefs = PreferenceManager.getDefaultSharedPreferences(EntryActivity.this.getApplicationContext());

            prefsEditor = appSharedPrefs.edit(); 

          prefsEditor.putString("10", tagTouchInterval);
          prefsEditor.putString("20", savePassword);
          prefsEditor.putString("30", allowChangeUser);
          prefsEditor.putString("40", displayRotaDetails);
          prefsEditor.putString("50", displayClientPhoneNumber);
          prefsEditor.putString("60", displayClientKeysafe);
          prefsEditor.putString("70", displayDoubleupCarer);
          prefsEditor.putString("80", displayContacts);
          prefsEditor.putString("90", autoLogout);
          prefsEditor.putString("100", displayNotesDisplayNotes);
          prefsEditor.putString("110", displayMeds);
          prefsEditor.putString("120", rotaLogout);
          prefsEditor.putString("130", displayActualTime);
          prefsEditor.putString("140", qrcodeEnabled);
          prefsEditor.putString("150", manualInput);
          prefsEditor.putString("160", rotasOnly);
          prefsEditor.commit();


    }//end of postExecute

我将发布 oncreate 的一部分,以便您可以看到事情的流程。该应用程序正在尝试在异步完成之前访问 SharedPreferences。我怎样才能解决这个问题?谢谢。

@Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        nfcscannerapplication = (NfcScannerApplication) getApplication();
        sIs = savedInstanceState;


        if(nfcscannerapplication.getCompId() == null || 
                                   nfcscannerapplication.getCompId().trim().equalsIgnoreCase("null")){ 
            Log.e(TAG, "compid null***********");
            showPasswordDialogBox();

        }


        setContentView(R.layout.entryscreen); 

        //loginWebservice = new LoginWebservice(this);
        loginWebservice = nfcscannerapplication.loginWebservice;
        userName = (EditText)findViewById(R.id.username);
        passwordPin = (EditText)findViewById(R.id.password);



        String isSavePassword = appSharedPrefs.getString("20", null);
        isAllowChangeUser = appSharedPrefs.getString("30", null);

【问题讨论】:

    标签: android android-asynctask


    【解决方案1】:

    使用onPostExecute() 中的共享首选项执行您需要做的任何事情,而不是在onCreate() 中。如果您愿意,请禁用您将更新的控件,或同时显示进度对话框或其他内容。

    更新:我应该补充一点,我看到了一些具有共同偏好的奇怪东西。我已经看到在提交后直接读取会给出错误的结果。不要使用共享偏好作为在您的活动中进行交流的方式。设置(实例)变量并改为调用回调。

    【讨论】:

    • 谢谢 你认为我使用 sharedpreferences 不正确吗?该应用程序的性质如下。这是一个将向同行业的不同公司推出的应用程序。每家公司都有一种叫做公司选项的东西,这是为每家公司定制应用程序的一种方式。因此,当您第一次安装应用程序时,会输入公司 ID,然后 Web 服务会获取该公司的选项。然后应用程序以定制的方式运行。我不能以这种方式使用公司选项吗?该应用程序可能有 15 个活动可以读取这些选项,所以我需要一种全局设置变量的方法
    • 我看到的问题是在压力测试期间,可能不会导致“真正的”问题。特别是在您的情况下,因为您没有更改共享首选项的值。但是,我只会使用共享首选项在执行之间本地存储状态。您可以考虑将这些设置存储在自定义应用程序对象中。这很容易从所有活动中访问。
    • 好的,我认为这是 sharedpreferences 的要点,以应用程序范围的方式共享数据?不是可以从应用程序的任何位置访问共享首选项吗?
    • 是的。但通常有更好的方式在应用程序的生命周期内与应用程序共享。我看到的问题是以前的一些版本(我认为是GB),所以现在可以解决了。
    【解决方案2】:

    我猜你在onCreate() 中对getString() 的最后两次调用返回null,因为你的AsyncTask 还没有完成。这就是多线程的异步特性,因此您必须考虑到这一点。首先我要搬家:

     String isSavePassword = appSharedPrefs.getString("20", null);
     isAllowChangeUser = appSharedPrefs.getString("30", null);
    

    进入您的 AsyncTask 的 onPostExecute()。然后我会认为它们在任何情况下都为空,显示一个对话框,表明应用程序尚未准备好或在某处停用按钮。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-28
      相关资源
      最近更新 更多