【问题标题】:How to put following code in AsyncTask如何将以下代码放入 AsyncTask
【发布时间】:2014-10-12 18:06:49
【问题描述】:

此代码用于将值传递给 php 页面并更新数据库中的一行 我需要以下代码才能进入异步任务,之后如何调用它等等。我收到 android.os.networkonmainthreadexception 错误。

    public void dbUpdate(ArrayList<NameValuePair> data, String php)
    {
    InputStream iS = null;

    try
    {
        HttpClient httpclient = new DefaultHttpClient();
        HttpPost httppost = new HttpPost(php);
        httppost.setEntity(new UrlEncodedFormEntity(data));
        HttpResponse response = httpclient.execute(httppost);
        HttpEntity entity = response.getEntity();
        iS = entity.getContent();
    }
    catch(Exception e)
    {
        Log.e("log_tag", "Error in http connection " + e.toString());
        Toast.makeText(getBaseContext(), "Error " + e.toString(), Toast.LENGTH_LONG).show();
    }
}

这是我按钮内的代码

public void Update(View v)
{
    try
    { 

        String nM = this.Name.getText().toString();
        String tP = this.Type.getText().toString();
        String bR = this.Breed.getText().toString();
        String gE = this.Gender.getText().toString();
        String iN = this.Injuries.getText().toString();
        String tR = this.Treat.getText().toString();

        ArrayList<NameValuePair> up = new ArrayList<NameValuePair>();
        up.add(new BasicNameValuePair("name", nM));
        up.add(new BasicNameValuePair("type", tP));
        up.add(new BasicNameValuePair("breed", bR));
        up.add(new BasicNameValuePair("gender", gE));
        up.add(new BasicNameValuePair("injuries", iN));
        up.add(new BasicNameValuePair("treatment", tR));

        String php = "http://select.garethprice.co.za/update.php?nM=" + nM;

        dbUpdate(up, php);

        Toast.makeText(getBaseContext(), "Successfully updated", Toast.LENGTH_LONG).show();
    }
    catch(Exception e)
    {
        Log.e("log_tag", "Error in uploading " + e.toString());
        Toast.makeText(getBaseContext(), "Error " + e.toString(), Toast.LENGTH_LONG).show();
    }
}

提前谢谢你!

【问题讨论】:

  • 必须是AsyncTask吗?
  • 是的,HTTP 请求必须在后台线程中执行,否则它们会在加载时停止 UI 线程中的所有其他操作。最直接的方法是使用 AsyncTask 类。

标签: php android android-asynctask


【解决方案1】:

像这样。这是一个非常简单的实现,但它涵盖了您的情况。

private class YourAsyncTask extends AsyncTask<Void, Void, Boolean>
{    
     @Override
     protected Void doInBackground(Void... arg0)
    {
        try
        {
             String nM = this.Name.getText().toString();
             String tP = this.Type.getText().toString();
             String bR = this.Breed.getText().toString();
             String gE = this.Gender.getText().toString();
             String iN = this.Injuries.getText().toString(); 
             String tR = this.Treat.getText().toString(); 

             ArrayList<NameValuePair> up = new ArrayList<NameValuePair>();
             up.add(new BasicNameValuePair("name", nM)); up.add(new BasicNameValuePair("type", tP));
             up.add(new BasicNameValuePair("breed", bR));
             up.add(new BasicNameValuePair("gender", gE)); up.add(new BasicNameValuePair("injuries", iN));
             up.add(new BasicNameValuePair("treatment", tR)); 

             String php = "http://select.garethprice.co.za/update.php?nM=" + nM; dbUpdate(up, php); 

            dbUpdate(up, php);
        }
       catch(Exception e)
       {
           Log.e("log_tag", "Error in uploading " + e.toString());
           Toast.makeText(getBaseContext(), "Error " + e.toString(), Toast.LENGTH_LONG).show(); 
          return false;
       }

        return true;
    }

     @Override
     protected void onPostExecute(Boolean result)
    {
         if (result)
         {
               Toast.makeText(getBaseContext(), "Successfully updated", Toast.LENGTH_LONG).show();
         }
    }
}

【讨论】:

  • 那我怎么称呼它?
  • new YourAsyncTask().execute();
  • 如何使我的变量全局化,以便我的两个类都可以使用它?
【解决方案2】:

Here 是一个关于 AsyncTask 的好教程。像这样需要连接到后端并获取数据的调用

HttpClient httpclient = new DefaultHttpClient();
    HttpPost httppost = new HttpPost(php);
    httppost.setEntity(new UrlEncodedFormEntity(data));
    HttpResponse response = httpclient.execute(httppost);
    HttpEntity entity = response.getEntity();
    iS = entity.getContent();

可以放入doInBackground(),而结果的处理可以在PostExeceute()方法中完成。

【讨论】:

    【解决方案3】:

    异步任务是一个类,可以在另一个类中调用以在后台线程中发出 HTTP 请求。您的 AsyncTask 类将被称为 dbUpdate。当您希望执行 AsyncTask 中的操作时,请在适当的方法或侦听器中包含以下行。

    new dbUpdate().execute();
    

    这将在外部类中,现在我们需要为 HTTP 发布请求配置 AsyncTask 类。创建一个public class dbUpdate extends AsyncTask&lt;String, String, String, String, String, String&gt;。现在这个类将有三个方法。

    @Override
    public void onPreExecute() { super.onPreExecute(); }
    protected String doInBackground(String... args) { /* more code here */ }
    @Override
    protected void onPostExecute(Boolean result) {
        super.onPostExecute(result);
        if(result) Toast.makeText(getBaseContext(), "Successfully updated", Toast.LENGTH_LONG).show();
    }
    

    现在,如果您希望任何代码在请求之前或之后运行,请将它们包含在 onPreExecuteonPostExecute 中的超级调用之后em>。 doInBackground 将是您的 HTTP 请求(以下代码)。您可以将所有字符串设为全局变量,以便可以在两个类中修改它们。

    String nM = this.Name.getText().toString();
    String tP = this.Type.getText().toString();
    String bR = this.Breed.getText().toString();
    String gE = this.Gender.getText().toString();
    String iN = this.Injuries.getText().toString(); 
    String tR = this.Treat.getText().toString();
    HttpClient httpclient = new DefaultHttpClient();
    HttpPost httppost = new HttpPost("http://select.garethprice.co.za/update.php?nM=" + nM);
    try{
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("name", nM));
        params.add(new BasicNameValuePair("type", tP));
        params.add(new BasicNameValuePair("breed", bR));
        params.add(new BasicNameValuePair("genders", gE));
        params.add(new BasicNameValuePair("issues", iN));
        params.add(new BasicNameValuePair("treatment", tR));
        httppost.setEntity(new UrlEncodedFormEntity(params));
        httpclient.execute(httppost);
    } catch (Exception e) {
        Log.e("log_tag", "Error in uploading " + e.toString());
        Toast.makeText(getBaseContext(), "Error " + e.toString(), Toast.LENGTH_LONG).show();
    }
    return null;
    

    【讨论】:

    • 如何使我的变量全局化,以便我的两个类都可以使用它?
    • 在两个类之外和上面声明变量
    • 如果这对您有帮助,如果您投票并选择最佳答案,我们将不胜感激
    【解决方案4】:

    它将类似于以下内容:

    public class MyAsyncTask extends AsyncTask<Void, Void, Boolean> {
    
         protected void onPreExecute() {
         }
    
         protected Boolean doInBackground(Void param) {
            InputStream iS = null;
    
            try
            {
                HttpClient httpclient = new DefaultHttpClient();
                HttpPost httppost = new HttpPost(php);
                httppost.setEntity(new UrlEncodedFormEntity(data));
                HttpResponse response = httpclient.execute(httppost);
                HttpEntity entity = response.getEntity();
                iS = entity.getContent();
            }
            catch(Exception e)
            {
                Log.e("log_tag", "Error in http connection " + e.toString());
                return false;
            }
    
            return true;
         }
    
         protected void onPostExecute(Boolean result) {
            if(result)
                Toast.makeText(getBaseContext(), "Successfully updated", Toast.LENGTH_LONG).show();
             else
                Toast.makeText(getBaseContext(), "Error " + e.toString(), Toast.LENGTH_LONG).show();
         }
    

    onPreExecuteonPostExecute 将在 UI 线程上调用。这意味着可以创建对话框、toast 等...

    doInBackground 将在新的工作线程上运行。这将运行您的网络代码。 doInBackgroundonPostExecute 返回一个布尔值,以指示是否应该显示您的 toast。

    然后你像这样在你的按钮上运行它:new MyAsyncTask().execute(); 替换这个调用:dbUpdate(up, php);

    Android 官方文档很好地解释了它:Android AsyncTask

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-08-09
      • 1970-01-01
      • 2019-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-13
      相关资源
      最近更新 更多