【问题标题】:make android AsynTask to wait for result使 android AsyncTask 等待结果
【发布时间】:2017-06-09 12:03:16
【问题描述】:

我想实现一个登录活动。它通过网络服务检查用户是否存在。

        EditText un=(EditText) findViewById(R.id.txtName);
        EditText pass=(EditText) findViewById(R.id.txtPass);
        WS ss=new WS();
        String str=ss.execute("checkLogin",un.getText().toString(),pass.getText().toString()).get();
        Intent in=new Intent(arg0.getContext(), Overview.class);
        in.putExtra("username", str);
        if(str=="No User")
            Toast.makeText(getApplicationContext(), "ss", 300).show();
        else
        {
            startActivity(in);
            finish();
        }

问题出在“IF”部分。完成代码行后设置“str”值。 但我想获得“str”值,然后检查 IF 以运行正确的操作。

【问题讨论】:

  • 将该代码放在AsyncTask 类的onPostExecute 方法中。
  • WS 类在一个单独的文件中。如何从 asyncTask 类的 postExecute 启动活动或更改编辑文本的值?有可能吗?
  • 要更新 UI,请将您的 WS 类设为内部类,而不是在新文件中创建它。这样您就可以访问扩展片段或 AppCompatActivity 的外部类的公共变量。
  • 我想检查信息是否真实,让用户查看概览活动...但我无法从该 asyncTask 开始新活动。

标签: android web-services android-asynctask


【解决方案1】:

你需要重写 onPostExecute 方法见下面的例子

private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
  protected Long doInBackground(URL... urls) {
      int count = urls.length;
      long totalSize = 0;
      for (int i = 0; i < count; i++) {
          totalSize += Downloader.downloadFile(urls[i]);
          publishProgress((int) ((i / (float) count) * 100));
      }
      return totalSize;
  }

  protected void onProgressUpdate(Integer... progress) {
      setProgressPercent(progress[0]);
  }

  protected void onPostExecute(Long result) {
      showDialog("Downloaded " + result + " bytes");
  }
}

【讨论】:

  • 我知道使用 Toast.maketext 或一些类似的函数,但我希望能够像在活动类中编码时那样行事。敌人示例开始一个活动
【解决方案2】:

异步任务的重点是不同步阻塞。如果您确实想要同步行为,您有多种选择:

  • 首先不要使用 AsyncTask(如果是长时间运行的网络调用,这可能不是一个好主意)
  • 将要在 AsyncTask 完成其后台工作后运行的代码放在 onPostExecute 方法中,该方法将可以访问从后台方法返回的数据的结果
  • 为 AsyncTask 提供一个回调,onPostExecute 可以在它完成时调用(在概念上与上一个选项相似,但更正式且对更改更健壮)

我更喜欢最后一个选项,但它也比其他选项花费更多的开发时间。

不要忘记 AsyncTask 可能会在后台工作和/或在 Activity 完成并关闭后完成,因此请确保在开始与 UI 交互之前适当地检查该状态。

【讨论】:

    【解决方案3】:

    如果您尝试进行网络调用,则不应使用 asynctask 而应使用 loopj 或 google 的 volley 库。

    Asynctask 不适合长时间的网络调用,这里有一个 asynctask 类的例子,代码:

        class AsyncTaskExample extends AsyncTask<Void, Integer, String> { 
        private  final String TAG = AsyncTaskExample.class.getName(); 
        protected void onPreExecute(){
        Log.d(TAG, "On preExceute...");
        }
    
        protected String doInBackground(Void...arg0) {
    
            Log.d(TAG, "On doInBackground...");
    
            for(int i = 0; i<5; i++){
                Integer in = new Integer(i);
                publishProgress(i);
            }
    
            return "You are at PostExecute";}
    
        protected void onProgressUpdate(Integer...a){
            Log.d(TAG,"You are in progress update ... " + a[0]);
        }
    
        protected void onPostExecute(String result) {
            Log.d(TAG,result); 
            }
        }
    

    根据需要编辑它,并在您想要进行检查时在您的代码中实例化一个新的, 希望对你有帮助

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-14
      • 2014-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-22
      • 1970-01-01
      • 2020-12-16
      相关资源
      最近更新 更多