Android DownloadFilesTask概念

问题描述:

在使用客户端服务器(获取mysql数据)的帮助下,我得到了许多错误。我只是看了一些线程在这里,我理解的是,最大的错误,我得到的HTTP connectionandroid.os.NetworkOnMainThreadException E/log_tagAndroid DownloadFilesTask概念

错误:错误转换结果显示java.lang.NullPointerException

可能因为我需要线程和处理程序之间的帮助任务。

我有以下代码,我理解这个概念,通常它应该工作。

package de.irgendwas; 

import android.app.Activity; 
import android.net.ParseException; 
import android.net.Uri; 
import android.os.AsyncTask; 
import android.os.Bundle; 
import android.util.Log; 
import android.widget.TextView; 
import android.widget.Toast; 

import com.google.android.gms.appindexing.Action; 
import com.google.android.gms.appindexing.AppIndex; 
import com.google.android.gms.appindexing.Thing; 
import com.google.android.gms.common.api.GoogleApiClient; 

import org.apache.http.HttpEntity; 
import org.apache.http.HttpResponse; 
import org.apache.http.client.HttpClient; 
import org.apache.http.client.methods.HttpPost; 
import org.apache.http.impl.client.DefaultHttpClient; 
import org.json.JSONArray; 
import org.json.JSONException; 
import org.json.JSONObject; 

import java.io.BufferedReader; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.net.URL; 

public class MainActivity extends Activity { 
    private GoogleApiClient client; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     /** Called when the activity is first created. */ 

     String result = null; 
     InputStream is = null; 
     StringBuilder sb = null; 

     //http post 
     try { 
      HttpClient httpclient = new DefaultHttpClient(); 
      HttpPost httppost = new HttpPost("http://localhost/connect_db.php"); 
      HttpResponse response = httpclient.execute(httppost); 
      HttpEntity entity = response.getEntity(); 
      is = entity.getContent(); 
      Log.e("log_tag", "connection established"); 
     } catch (Exception e) { 
      Log.e("log_tag", "Error in http connection" + e.toString()); 
     } 

     //convert response to string 
     try { 
      BufferedReader reader = new BufferedReader(new InputStreamReader(is, "utf-8"), 8); 
      sb = new StringBuilder(); 
      sb.append(reader.readLine() + "\n"); 
      String line = "0"; 
      while ((line = reader.readLine()) != null) { 
       sb.append(line + "\n"); 
      } 
      is.close(); 
      result = sb.toString(); 
     } catch (Exception e) { 
      Log.e("log_tag", "Error converting result " + e.toString()); 
     } 

     //paring data 
     int fd_id = 0; 
     String fd_name = ""; 
     try { 
      JSONArray jArray = new JSONArray(result); 
      JSONObject json_data = null; 
      Toast.makeText(getBaseContext(), "1. try Block", Toast.LENGTH_LONG).show(); 
      for (int i = 0; i < jArray.length(); i++) { 
       json_data = jArray.getJSONObject(i); 
       fd_id = json_data.getInt("artist"); 
       fd_name = json_data.getString("title"); 
      } 
     } catch (JSONException e1) { 
      Toast.makeText(getBaseContext(), "No Data Found", Toast.LENGTH_LONG).show(); 
     } catch (ParseException e1) { 
      e1.printStackTrace(); 
     } 

     //print received data 
     TextView t = (TextView) findViewById(R.id.text); 
     t.setText("ID: " + fd_id + " Name: " + fd_name); 
     // ATTENTION: This was auto-generated to implement the App Indexing API. 
     // See https://g.co/AppIndexing/AndroidStudio for more information. 
     client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build(); 
    } 

    /** 
    * ATTENTION: This was auto-generated to implement the App Indexing API. 
    * See https://g.co/AppIndexing/AndroidStudio for more information. 
    */ 
    public Action getIndexApiAction() { 
     Thing object = new Thing.Builder() 
       .setName("Main Page") // TODO: Define a title for the content shown. 
       // TODO: Make sure this auto-generated URL is correct. 
       .setUrl(Uri.parse("http://[ENTER-YOUR-URL-HERE]")) 
       .build(); 
     return new Action.Builder(Action.TYPE_VIEW) 
       .setObject(object) 
       .setActionStatus(Action.STATUS_TYPE_COMPLETED) 
       .build(); 
    } 

    @Override 
    public void onStart() { 
     super.onStart(); 

     // ATTENTION: This was auto-generated to implement the App Indexing API. 
     // See https://g.co/AppIndexing/AndroidStudio for more information. 
     client.connect(); 
     AppIndex.AppIndexApi.start(client, getIndexApiAction()); 
    } 

    @Override 
    public void onStop() { 
     super.onStop(); 

     // ATTENTION: This was auto-generated to implement the App Indexing API. 
     // See https://g.co/AppIndexing/AndroidStudio for more information. 
     AppIndex.AppIndexApi.end(client, getIndexApiAction()); 
     client.disconnect(); 
    } 

} 

我不会发布PHP脚本在服务器上,因为如果我通过浏览器调用的URL得当提供我TESTDATA,所以它应该是罚款。

现在,当执行应用程序时,我得到上述错误。在搜索网页时,我发现了DownloadFilesTask概念,听起来它应该是解决方案。但我不明白,我无法在我的代码中实现它。有人可以帮助,或者除了developer.android之外,还有其他地方的教程。

发生此错误是因为您想在UI线程中执行与网络相关的进程。你需要将它从你的UI线程中移走。对于你的情况,你可以使用AsyncTask

AsyncTask是一种在后台线程中执行操作而不必手动处理线程创建或执行的机制。 AsyncTasks被设计为用于短操作(最多几秒),您可能想要使用Service和/或Executor来执行很长时间的运行任务。

AsyncTask通常用于无法在UI线程上执行的长时间运行的任务,例如从API下载网络数据或从设备上其他位置索引数据。

请阅读Creating and Executing Async Tasks

在这里,在网络相关的过程中example for using AsyncTask

public class MainActivity extends Activity { 
    private ImageView ivBasicImage; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     ivBasicImage = (ImageView) findViewById(R.id.ivBasicImage); 
     String url = "https://i.imgur.com/tGbaZCY.jpg"; 
     // Download image from URL and display within ImageView 
     new ImageDownloadTask(ivBasicImage).execute(url); 
    } 

    // Defines the background task to download and then load the image within the ImageView 
    private class ImageDownloadTask extends AsyncTask<String, Void, Bitmap> { 
     ImageView imageView; 

     public ImageDownloadTask(ImageView imageView) { 
      this.imageView = imageView; 
     } 

     protected Bitmap doInBackground(String... addresses) { 
      Bitmap bitmap = null; 
      InputStream in; 
      try { 
       // 1. Declare a URL Connection 
       URL url = new URL(addresses[0]); 
       HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 
       // 2. Open InputStream to connection 
       conn.connect(); 
       in = conn.getInputStream(); 
       // 3. Download and decode the bitmap using BitmapFactory 
       bitmap = BitmapFactory.decodeStream(in); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } finally { 
       if(in != null) 
       in.close(); 
      } 
      return bitmap; 
     } 

     // Fires after the task is completed, displaying the bitmap into the ImageView 
     @Override 
     protected void onPostExecute(Bitmap result) { 
      // Set bitmap image for the result 
      imageView.setImageBitmap(result); 
     } 
    } 
} 

你也应该得到这个异常登录 Log.e("log_tag", "Error in http connection" + e.toString());
这是因为该行

HttpPost httppost = new HttpPost("http://localhost/connect_db.php"); 

这将始终指向的设备的本地主机,而不是服务器。所以,你应该使用:

HttpPost httppost = new HttpPost("http://10.0.2.2/connect_db.php"); 

这是空指针异常的原因上result

+0

没有,我改变了与本地主机 –

+0

@软柔的原始地址我建议编辑的名字,因为我认为这个信息在问题中是需要的,因为它不能被假定。避免任何其他人遵循此路径。 – Bantu

+0

我改变了脚本使用HttpURLConnection,现在它工作得很好,也结合了AsyncTask,所以我明白了。 –