Android URL 连接和线程问题,以及 IllegalStateExceptions

Android problems with URL connection and threading, and IllegalStateExceptions

这是 class,应该允许我连接到 url 并从中检索数据。它将 JSON 数据转换为字符串。也许这里有问题,我看不到。我对这种编程还很陌生。

public class NetworkConnection extends AsyncTask<String, Void, String> {
private static final String DEBUG_TAG = "HttpExample";




protected String doInBackground(String... urls) {
    try{
        return downloadUrl(urls[0]);
    } catch (IOException e) {
        return "Unable to retrieve Web Page";
    }
}

//Fetch the data from the URL
public String downloadUrl(String myurl) throws IOException {
    InputStream is = null;
    int len = 500;
    String text = new String();

    try {
        URL url = new URL(myurl);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setReadTimeout(10000 /* milliseconds */);
        conn.setConnectTimeout(15000 /* milliseconds */);
        conn.setRequestMethod("GET");
        conn.setDoInput(true);

        // Starts the query
        conn.connect();
        int response = conn.getResponseCode();
        Log.d(DEBUG_TAG, "The response is: " + response);
        is = conn.getInputStream();

        try {
                    BufferedReader br = new BufferedReader(
                            new InputStreamReader(
                                    conn.getInputStream()));
                    StringBuilder sb = new StringBuilder();
                    String line;
                    while ((line = br.readLine()) != null) {
                        sb.append(line + "\n");
                    }
                    br.close();
                    JSONArray data = new JSONArray(sb.toString());
                    for (int i = 0; i < data.length(); i++) {
                        JSONObject row = data.getJSONObject(i);
                        String klasse = row.getString("K_Nr");
                        String raum = row.getString("K_Raum");
                        text = text + klasse + ": " + raum + "\n";
                    }
        } catch (IOException e) {

        } catch (JSONException e) {
            e.printStackTrace();
        }


    } finally {
        if (is != null) {
            is.close();
        }
    }
    return text;
}

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

}

这是主线程UI所在的class。在这里,我尝试通过 class 网络连接访问 url。问题是我不知道如何正确穿线。

public class Start extends Activity {
// public String  URL = new String("http://10.0.2.2/?action=getKlassen");
// public String  URL = new String("http://127.0.0.1/webservice/ajax.php?action=getKlassen");
public String  URL;
NetworkConnection netCon;
public TextView testAusgabe;


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    Intent i = getIntent();
    String val = i.getStringExtra("Klasse");
    TextView ausgabe = (TextView) findViewById(R.id.ausgabe);
    testAusgabe = (TextView)findViewById(R.id.testAusgabe);
    netCon = new NetworkConnection();
    URL = new String("http://10.0.2.2/?action=getKlassen");
    ausgabe.setText(val);

}

public void myClickHandler(View view) {
    ConnectivityManager connMgr = (ConnectivityManager)
            getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
    if (networkInfo != null && networkInfo.isConnected()) {
        new NetworkConnection().execute(URL);
    } else {
        testAusgabe.setText("No network connection available.");
    }
}

public void onClick(View view){

}

public void zeigeListe_Click (View view) {

    startActivity(new Intent(this, KlassenView.class));
}
public void ladeDaten_Click(View view) {
    String data;

    data = netCon.doInBackground(URL);
    testAusgabe.setText(data);
}

}

这里我们有抛出的异常。当我单击应该加载数据的按钮时,应用程序崩溃了。它肯定有线程问题,但我不明白其他例外情况。如果有人可以提供帮助,那就太好了。提前致谢。

01-29 11:10:38.776 6648-6648/com.example.httptest E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.httptest, PID: 6648
java.lang.IllegalStateException: Could not execute method for android:onClick
 at android.view.View$DeclaredOnClickListener.onClick(View.java:4452)
 at android.view.View.performClick(View.java:5198)
 at android.view.View$PerformClick.run(View.java:21147)
 at android.os.Handler.handleCallback(Handler.java:739)
 at android.os.Handler.dispatchMessage(Handler.java:95)
 at android.os.Looper.loop(Looper.java:148)
 at android.app.ActivityThread.main(ActivityThread.java:5417)
 at java.lang.reflect.Method.invoke(Native Method)
 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.reflect.InvocationTargetException
 at java.lang.reflect.Method.invoke(Native Method)
 at android.view.View$DeclaredOnClickListener.onClick(View.java:4447)
 at android.view.View.performClick(View.java:5198) 
 at android.view.View$PerformClick.run(View.java:21147) 
 at android.os.Handler.handleCallback(Handler.java:739) 
 at android.os.Handler.dispatchMessage(Handler.java:95) 
 at android.os.Looper.loop(Looper.java:148) 
 at android.app.ActivityThread.main(ActivityThread.java:5417) 
 at java.lang.reflect.Method.invoke(Native Method) 
 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
Caused by: android.os.NetworkOnMainThreadException
 at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1273)
 at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:110)
 at libcore.io.IoBridge.connectErrno(IoBridge.java:154)
 at libcore.io.IoBridge.connect(IoBridge.java:122)
 at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:183)
 at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:452)
 at java.net.Socket.connect(Socket.java:884)
 at com.android.okhttp.internal.Platform.connectSocket(Platform.java:117)
 at com.android.okhttp.internal.http.SocketConnector.connectRawSocket(SocketConnector.java:160)
 at com.android.okhttp.internal.http.SocketConnector.connectCleartext(SocketConnector.java:67)
 at com.android.okhttp.Connection.connect(Connection.java:152)
 at com.android.okhttp.Connection.connectAndSetOwner(Connection.java:185)
 at com.android.okhttp.OkHttpClient.connectAndSetOwner(OkHttpClient.java:128)
 at com.android.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:341)
 at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:330)
 at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:248)
 at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:433)
 at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:114)
 at com.example.httptest.NetworkConnection.downloadUrl(NetworkConnection.java:50)
 at com.example.httptest.NetworkConnection.doInBackground(NetworkConnection.java:29)
 at com.example.httptest.Start.ladeDaten_Click(Start.java:62)
 at java.lang.reflect.Method.invoke(Native Method) 
 at android.view.View$DeclaredOnClickListener.onClick(View.java:4447) 
 at android.view.View.performClick(View.java:5198) 
 at android.view.View$PerformClick.run(View.java:21147) 
 at android.os.Handler.handleCallback(Handler.java:739) 
 at android.os.Handler.dispatchMessage(Handler.java:95) 
 at android.os.Looper.loop(Looper.java:148) 
 at android.app.ActivityThread.main(ActivityThread.java:5417) 
 at java.lang.reflect.Method.invoke(Native Method) 
 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

您可以在 LogCat 中看到您有一个 NetworkOnMainThreadException

如果您试图在主线程中执行网络代码,就会出现这种异常。

对此类代码使用 AsyncTask 或线程。

其实!你在你的代码中犯了一个错误。 你必须使用
netCon.execute(URL);代替 netCon.doInBackground(URL); 一旦调用了 execute() 方法,并且在完成之前的 doInBackground() 之前再次单击以启动该方法,则会再次发生异常。 所以做一件事: 在方法 onPreExecute() 中,防止您的按钮再次被点击,在 onPostExecute() 中,使其再次可点击。

因此,通过这种方式您可以防止创建新线程。 干杯!