【问题标题】:Passing string from doInBackground of Async task to main thread将字符串从异步任务的 doInBackground 传递到主线程
【发布时间】:2014-01-06 05:52:33
【问题描述】:

这里是 Java 新手。

我正在尝试在我的异步任务中的doInBackground() 中设置一个 TextView。根据我的研究,我无法修改这样做的主线程,所以在这里搞乱 TextViews 是不可能的。所以我想做的是使用字符串。我需要这个字符串可以在主类中访问。

我该怎么做?

我尝试了String loginresult = "Login Successful! Please Wait...";,但我无法在任何地方访问该字符串。我尝试将其标记为public,但这是 doInBackground() 中的非法修饰符。

也许字符串不是最好的方法,如果是这样,你们所有的天才会建议什么?

这是我的异步代码,我在有问题的地方放了箭头。对此菜鸟的任何帮助将不胜感激:)

class PostTask extends AsyncTask<String, Integer, String> {
           @Override
           protected void onPreExecute() {
              super.onPreExecute();



           }

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


               try {
                    List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
                    nameValuePairs.add(new BasicNameValuePair("username", username));
                    nameValuePairs.add(new BasicNameValuePair("password", password));
                    httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

                    // Execute HTTP Post Request
                    Log.w("SENCIDE", "Execute HTTP Post Request");
                    //Executes link, login.php returns true if username and password match in db 
                    HttpResponse response = httpclient.execute(httppost);

                   String str = inputStreamToString(response.getEntity().getContent()).toString();
                    Log.w("SENCIDE", str);

                    if(str.toString().equalsIgnoreCase("true"))
                    {
                        Log.w("SENCIDE", "TRUE");
      ----->                result.setText("Login Successful! Please Wait...");   
                    }else
                    {
                        Log.w("SENCIDE", "FALSE");
    ------>             result.setText(str);                
                    }

                } catch (ClientProtocolException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }



              // Dummy code
              for (int i = 0; i <= 100; i += 5) {
                try {
                  Thread.sleep(50);
                } catch (InterruptedException e) {
                  e.printStackTrace();
                }
                 publishProgress(i);
              }
              return "All Done!";
           }//end doinbackground

            StringBuilder inputStreamToString(InputStream is) {
                String line = "";
                StringBuilder total = new StringBuilder();
                // Wrap a BufferedReader around the InputStream
                BufferedReader rd = new BufferedReader(new InputStreamReader(is));
                // Read response until the end
                try {
                    while ((line = rd.readLine()) != null) { 
                        total.append(line); 
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
                // Return full string
                return total;
            }//end StringBuilder

           @Override
           protected void onProgressUpdate(Integer... values) {
              super.onProgressUpdate(values);

           }

           @Override
           protected void onPostExecute(String result) {
              super.onPostExecute(result);

                // turns the text in the textview "Tbl_result" into a text string called "tblresult"
                TextView tblresult = (TextView) findViewById(R.id.tbl_result);




        // If "tblresult" text string matches the string "Login Successful! Please Wait..." exactly, it will switch to next activity
                if (tblresult.getText().toString().equals("Login Successful! Please Wait...")) {
                      Intent intent = new Intent(NewAndroidLogin.this, Homepage.class);
                     //take text in the username/password text boxes and put them into an extra and push to next activity 
                      EditText uname2 = (EditText)findViewById(R.id.txt_username);
                      String username2 = uname2.getText().toString();
                      EditText pword2 = (EditText)findViewById(R.id.txt_password);
                      String password2 = pword2.getText().toString();
                      intent.putExtra("username2", username2 + "&pword=" + password2);
                      startActivity(intent);
                   }

           }//end onPostExecute
           }//end async task

【问题讨论】:

    标签: java android asynchronous android-asynctask


    【解决方案1】:

    将您的AsyncTask 更改为使用String 作为进度参数类型:

    AsyncTask<String, String, String>
    

    更改onProgressUpdate() 以更新进度

    @Override
    protected void onProgressUpdate(String... values) {
        result.setText(values[0]);
    }
    

    然后汇报进度:

    if(str.toString().equalsIgnoreCase("true"))
    {
        Log.w("SENCIDE", "TRUE");
        publishProgress("Login Successful! Please Wait...");   
    }else
    {
        Log.w("SENCIDE", "FALSE");
        publishProgress(str);                
    }
    

    【讨论】:

    • 非常感谢你,这就像一个魅力。我将来肯定会使用的很棒的小技巧。谢谢你,我的朋友。
    【解决方案2】:

    将String loginresult = "Login Successful! Please Wait..."; 设为全局并

    runOnUiThread(new Runnable() {
    @Override
    public void run() {
    str = inputStreamToString(response.getEntity().getContent()).toString();
    if(str.toString().equalsIgnoreCase("true"))
    {
     Log.w("SENCIDE", "TRUE");
     result.setText("Login Successful! Please Wait...");   
    }
    else
    {
     Log.w("SENCIDE", "FALSE");
     result.setText(str);                
    }
    }
    } );
    

    【讨论】:

      【解决方案3】:

      在类级别声明处理程序:

       Handler handler;
      

      在Activity的onCreate()方法中初始化Handler:

      // Doing this inside the onCreate() method of Activity
      // will help the handler to hold the reference to this Activity.
      
       handler = new Handler();
      

      在后台线程中调用它:

       @Override
       protected String doInBackground(String... params) {
      
          handler.post(new Runnable(){
      
          public void run(){
      
             // SET UI COMPONENTS FROM HERE.
          }
      
         });
       }
      

      【讨论】:

      • 那么我将如何在主线程上检索它?命令是什么?
      • @user3155326 您可以在此处从run() 方法内部访问您的主 UI 线程组件。调用 handler.post(); 可以让你访问主 UI 线程,现在你可以做一些事情,比如在 TextView 中设置文本等。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多