0

チュートリアルの助けを借りてクライアント サーバー (mysql データのフェッチ) を試しているときに、多くのエラーが発生します。ここでいくつかのスレッドを読んだところ、最大のエラーが発生することがわかりました

http 接続のエラーandroid.os.NetworkOnMainThreadException E/log_tag: 結果の変換エラー 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 を呼び出すと、テストデータが適切に配信されるため、問題ないはずです。

アプリの実行中に上記のエラーが発生します。Web を検索しているときに DownloadFilesTask の概念を見つけましたが、それが解決策であるように思えます。しかし、私はそれを取得できません。コードに実装することはできません。誰かが助けてくれますか、またはdeveloper.androidのもの以外のどこかに良いチュートリアルがありますか.

4

2 に答える 2

1

このエラーは、UI スレッドでネットワーク関連のプロセスを実行したいために発生します。UI スレッドから離す必要があります。あなたの場合、AsyncTaskを使用できます。

AsyncTask は、スレッドの作成や実行を手動で処理することなく、バックグラウンド スレッドで操作を実行するためのメカニズムです。AsyncTasks は短い操作 (せいぜい数秒) に使用するように設計されており、非常に長時間実行されるタスクには Service や Executor を使用することができます。

AsyncTask は通常、API からのネットワーク データのダウンロードや、デバイスの他の場所からのデータのインデックス作成など、UI スレッドでは実行できない長時間実行されるタスクに使用されます。

非同期タスクの作成と実行をお読みください。

ネットワーク関連のプロセスで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);
        }
    }
}
于 2016-12-27T18:05:12.187 に答える
0

この例外もログに記録する必要があります 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");  

これが nullpointer 例外の原因ですresult

于 2016-12-27T18:17:19.363 に答える