私にはこの例外があり、これに関するスレッドを読んでいて、混乱しているように見えました:
Android.os.NetworkOnMainThreadExceptionの修正方法
マニフェストにすでに次の行を追加しました。
<uses-permission Android:name="Android.permission.INTERNET" />
その議論で、彼らは、ネットワーキングを行うことができないアプリのメイン実行スレッドについて話します。私が不思議に思っているのは、コードをAndroidの優れた慣行と一致するように再構築する方法です。
これは私のアクティビティクラスです。
package com.problemio;
import Java.io.InputStream;
import Java.util.ArrayList;
import org.Apache.http.HttpEntity;
import org.Apache.http.HttpResponse;
import org.Apache.http.NameValuePair;
import org.Apache.http.client.HttpClient;
import org.Apache.http.client.entity.UrlEncodedFormEntity;
import org.Apache.http.client.methods.HttpPost;
import org.Apache.http.impl.client.DefaultHttpClient;
import org.Apache.http.message.BasicNameValuePair;
import Android.app.Activity;
import Android.content.Intent;
import Android.os.Bundle;
import Android.util.Log;
import Android.view.View;
import Android.widget.Button;
import Android.widget.EditText;
public class LoginActivity extends Activity
{
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.login);
// Show form for login_email
final EditText loginEmail = (EditText) findViewById(R.id.login_email);
String name = loginEmail.getText().toString();
// Show field for password
final EditText password = (EditText) findViewById(R.id.password);
String text = password.getText().toString();
// Show button for submit
Button submit = (Button)findViewById(R.id.submit);
// Show options for create-profile and forgot-password
submit.setOnClickListener(new Button.OnClickListener()
{
public void onClick(View v)
{
String email = loginEmail.getText().toString();
String pass = password.getText().toString();
sendFeedback(pass, email);
}
});
}
public void sendFeedback(String pass , String email)
{
Log.d( "1" , pass );
Log.d( "1" , email );
// Go to db and check if these r legit
// How do I do that? :)
ArrayList<NameValuePair> postParameters = new ArrayList<NameValuePair>();
postParameters.add(new BasicNameValuePair("username", email ));
postParameters.add(new BasicNameValuePair("password", pass ));
String responseString = null;
try
{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("myUrl");
// no idea what this does :)
httppost.setEntity(new UrlEncodedFormEntity(postParameters));
// This is the line that send the request
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent();
}
catch (Exception e)
{
Log.e("log_tag", "Error in http connection "+e.toString());
}
}
}
ここで何が間違っていますか、どうすれば修正できますか? :)ありがとう!!
NetworkOnMainThreadException:アプリケーションがメインスレッドでネットワーク操作を実行しようとしたときにスローされる例外。
Asynctaskでsendfeedbackメソッドを呼び出すと、上記のコードのみが機能します。 Webサーバーが応答するのに多くの時間がかかるため、メインスレッドが応答しなくなります。それを回避するには、別のスレッドで呼び出す必要があります。したがって、asynctaskの方が優れています。
asynctaskの使用方法を示す link
NetworkOnMainThreadExceptionは、アプリがメインスレッドでネットワーク操作を試みるとスローされます。
これを修正するには、アクティビティ内でサーバー呼び出しを行うAndroid.os.AsyncTask<Params, Progress, Result>
を拡張するプライベート内部クラスを使用します。
何かとして、
private class SendfeedbackJob extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String[] params) {
// do above Server call here
return "some message";
}
@Override
protected void onPostExecute(String message) {
//process message
}
}
そして、以下のようにsubmit.setOnClickListener
から上記のクラスを呼び出します。
SendfeedbackJob job = new SendfeedbackJob();
job.execute(pass, email);
if (Android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
try
{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("myUrl");
// no idea what this does :)
httppost.setEntity(new UrlEncodedFormEntity(postParameters));
// This is the line that send the request
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent();
}
catch (Exception e)
{
Log.e("log_tag", "Error in http connection "+e.toString());
}
これがあなたの問題です。 API 11以降、この例外はUIスレッド(クラスのhttp通信)で長いタスクを実行していることを通知し、新しいStrictGuardポリシーによるとこれは不可能です。だから、2つの異なる選択肢があります
以下のように非同期クラスを作成できます
class Retrievedata extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... params) {
try{
//Your code
}
return null;
}
}
DoInBackgroundメソッド内にすべてのコードを置くことができます
Androidルールに反するメインスレッドでネットワーク呼び出しを行ったため、asynctaskやハンドラーなどの別のスレッドでネットワーク呼び出しを行う必要があります。
長い調査(半日続く)の後、ここに示された問題に似た問題の解決策を見つけました。 myAndroid Studio 2.3.3によって表示される例外は次のとおりです。
AndroidスタジオAndroid.os.networkonmainthreadexception
この問題は、MainActivityでUI変数を設定できないことに基づいていました。そこで、私は次のビデオを見て、問題を解決しました。他の人にも役立つことを願っています:
メインスレッドはUIスレッドであり、ユーザーインタラクションをブロックする可能性のあるメインスレッドで操作を行うことはできません。これを回避するには、必要に応じて単純なハンドラーを作成し、メインスレッドを更新します。
Runnable runnable;
Handler newHandler;
newHandler = new Handler();
runnable = new Runnable() {
@Override
public void run() {
try {
//update UI
} catch (Exception e) {
e.printStackTrace();
}
}
};
runnable.run();
スレッドの使用を停止するには
newHandler.removeCallbacks(runnable);
詳細については、こちらをご覧ください。 https://Android-developers.googleblog.com/2009/05/painless-threading.html
このリンクを見てください: https://developer.Android.com/reference/Android/os/NetworkOnMainThreadException.html
アプリケーションがメインスレッドでネットワーク操作を実行しようとしたときにスローされる例外。 SDKの以前のバージョンを対象とするアプリケーションは、メインイベントループスレッドでネットワーキングを行うことができますが、お勧めできません。
minSdkVersion <11を設定すると、アプリケーションが動作し、メインスレッドでネットワーク操作を実行できます。