Получить объект JSON из URL с помощью HTTPURLConnection на Android
В настоящее время я пытаюсь получить доступ к объекту JSON в моем приложении для Android. Тем не менее, я продолжаю получать следующую ошибку:
android.os.NetworkOnMainThreadException
После небольшого исследования, единственной информацией, которую я имею в настоящее время, является то, что мне нужно делать это асинхронно (?)
Вот мой код:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView dynamictext;
dynamictext = (TextView) findViewById(R.id.dynamictext);
dynamictext.setText(getJSON("my url here"));
}
public String getJSON(String url) {
HttpURLConnection c = null;
try {
URL u = new URL(url);
c = (HttpURLConnection) u.openConnection();
c.connect();
int status = c.getResponseCode();
switch (status) {
case 200:
case 201:
BufferedReader br = new BufferedReader(new InputStreamReader(c.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line+"\n");
}
br.close();
return sb.toString();
}
} catch (Exception ex) {
return ex.toString();
} finally {
if (c != null) {
try {
c.disconnect();
} catch (Exception ex) {
//disconnect error
}
}
}
return null;
}
}
заранее спасибо
4 ответа
Я рекомендую прочитать этот URL /questions/43554177/kak-ya-mogu-ispravit-androidosnetworkonmainthreadexception/43554209#43554209
добавить AsyncTask;
public class TestAsyncTask extends AsyncTask<Void, Void, String> {
private Context mContext;
private String mUrl;
public TestAsyncTask(Context context, String url) {
mContext = context;
mUrl = url;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
dynamictext = (TextView) findViewById(R.id.dynamictext);
}
@Override
protected String doInBackground(Void... params) {
String resultString = null;
resultString = getJSON(mUrl);
return resultString;
}
@Override
protected void onPostExecute(String strings) {
super.onPostExecute(strings);
dynamictext.setText(strings);
}
private String getJSON(String url) { ... }
}
использовать AsyncTask;
public class MainActivity ... {
private TextView dynamictest;
onCreate() {
...
TestAsyncTask testAsyncTask = new TestAsyncTask(MainActivity.this, "my url here");
testAsyncTask.execute();
}
}
Начиная с Android 3 и выше, сетевые операции, выполняемые в потоке пользовательского интерфейса, запрещены, и, следовательно, ваше приложение будет аварийно завершать работу из-за NetworkOnMainThreadException
,
Здесь вы можете найти простой пример Asyntask
который вы будете обрабатывать свой код асинхронно: Android: AsyncTask, чтобы сделать HTTP-запрос GET?
private void taskPostExecute(String url)
{
myTask2=(RequestTask)new RequestTask().execute(url);
}
class RequestTask extends AsyncTask<String, String, String> {
@Override
protected String doInBackground(String... uri) {
try {
postData(uri[0]);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onCancelled() {
myTask2.cancel(true);
}
@Override
protected void onPostExecute(String url) {
LinearLayouts();
}
}
public static String postData(String url) throws UnsupportedEncodingException {
HttpClient httpclient = new DefaultHttpClient();
HttpGet httppost = new HttpGet(url);
String responseString = "";
try {
HttpResponse response = httpclient.execute(httppost);
StatusLine statusLine = response.getStatusLine();
InputStream inputStream = null;
if(statusLine.getStatusCode() == HttpStatus.SC_OK){
inputStream = response.getEntity().getContent();
if(inputStream != null)
responseString = convertInputStreamToString(inputStream);
else
responseString = "Did not work!";
JSONObject reader = null;
JSONArray sys = null;
try {
reader = new JSONObject(responseString);
String res_metar = reader.getString("TAG");
} catch (JSONException e) {
e.printStackTrace();
}
//a = responseString;
} else{
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch (ClientProtocolException e) {
} catch (IOException e) {
// process execption
}
return responseString;
}
private static String convertInputStreamToString(InputStream inputStream) throws IOException{
BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(inputStream));
String line = "";
String result = "";
while((line = bufferedReader.readLine()) != null)
result += line;
inputStream.close();
return result;
}
Вы можете попробовать это, это работает.
Чтобы выполнить трудоемкую задачу, вам необходимо реализовать асинхронную задачу, которая будет выполняться в потоке без пользовательского интерфейса, поскольку вы не можете выполнять такие операции в потоке пользовательского интерфейса.
И вы можете выполнить асинхронную задачу в методе onStart() вашей активности и переопределить onPostMethod() асинхронной задачи, чтобы реализовать любые изменения, которые вы хотите сделать в пользовательском интерфейсе после проверки сетевой операции http://developer.android.com/reference/android/os/AsyncTask.html для получения подробной информации о задаче Async.