在 Fragments 中使用 JSON 时,应用在 Android 开发中没有响应
Posted
技术标签:
【中文标题】在 Fragments 中使用 JSON 时,应用在 Android 开发中没有响应【英文标题】:When using JSON in Fragments the app is not responding in Android Development 【发布时间】:2014-01-12 08:32:20 【问题描述】:我在 android 中使用导航抽屉。我通过 JSON 从 URL 获取数据。当我在加载片段时运行应用程序时出现错误提示
“很遗憾,App 没有回应” 我从 php 文件中获取 JSON 数据,它是从 INTERNET 获取的,现在它位于 localhost 中。
我的片段类是:
import java.util.ArrayList;
import java.util.HashMap;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class QMFragment extends Fragment
public QMFragment()
// url to make request
private static String url = "http://localhost/app/qm_data.php";
// JSON Node names
private static final String TAG_QM = "qm";
private static final String TAG_ID = "id";
private static final String TAG_NAME = "name";
private static final String TAG_URL = "url";
// Hashmap for ListView
ArrayList<HashMap<String, String>> contactList = new ArrayList<HashMap<String, String>>();
// JSONArray
JSONArray qmArray = null;
// Creating JSON Parser instance
JSONParser jParser = new JSONParser();
// getting JSON string from URL
JSONObject json = jParser.getJSONFromUrl(url);
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
View rootView = inflater.inflate(R.layout.fragment_qm, container, false);
getData();
return rootView;
public void getData()
try
// Getting Array
qmArray = json.getJSONArray(TAG_QM);
// looping through All Data
for(int i = 0; i < qmArray.length(); i++)
JSONObject c = qmArray.getJSONObject(i);
// Storing each json item in variable
String id = c.getString(TAG_ID);
String name = c.getString(TAG_NAME);
String url = c.getString(TAG_URL);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(TAG_ID, id);
map.put(TAG_NAME, name);
map.put(TAG_URL, url);
// adding HashList to ArrayList
contactList.add(map);
catch (JSONException e)
e.printStackTrace();
我的 JSONParser.java 是:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;
import android.util.Log;
public class JSONParser
static InputStream is = null;
static JSONObject jObj = null;
static String json = "";
// constructor
public JSONParser()
public JSONObject getJSONFromUrl(String url)
// Making HTTP request
try
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
catch (UnsupportedEncodingException e)
e.printStackTrace();
catch (ClientProtocolException e)
e.printStackTrace();
catch (IOException e)
e.printStackTrace();
try
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null)
sb.append(line + "\n");
is.close();
json = sb.toString();
catch (Exception e)
Log.e("Buffer Error", "Error Converting Result " + e.toString());
// try parse the string to a JSON object
try
jObj = new JSONObject(json);
catch (JSONException e)
Log.e("JSON Parser", "Error Parsing Data " + e.toString());
// return JSON String
return jObj;
我的 XML 是:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:background="@color/bg" >
<TextView
android:id="@+id/txtLabel"
android:layout_
android:layout_
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="40dp"
android:layout_marginTop="5dp"
android:text="@string/head"
android:textColor="@color/text_color"
android:textSize="25sp" />
<TextView
android:layout_
android:layout_
android:layout_alignParentLeft="true"
android:layout_below="@+id/txtLabel"
android:layout_marginTop="5dp"
android:background="#CCCCCC" />
<ScrollView
android:id="@+id/scrollView1"
android:layout_
android:layout_
android:layout_below="@+id/txtLabel"
android:layout_marginTop="10dp" >
<RelativeLayout
android:id="@+id/navigate_RLayout"
android:layout_
android:layout_ >
<TextView
android:id="@+id/txtqmhead"
android:layout_
android:layout_
android:text="@string/qm_heading"
android:textSize="25sp"
android:textColor="@color/text_color" />
<TextView
android:id="@+id/txtqmsub"
android:layout_
android:layout_
android:text="@string/qm_chn"
android:textSize="18sp"
android:textColor="@color/text_color"
android:layout_below="@+id/txtqmhead"
android:layout_marginLeft="28dp" />
<TableLayout
android:id="@+id/tbl"
android:layout_
android:layout_
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_below="@+id/txtqmsub"
android:layout_marginTop="20dp" >
</TableLayout>
</RelativeLayout>
</ScrollView>
</RelativeLayout>
PHP 文件是:
<?php
header('Content-type: application/json');
$server = "localhost";
$username = "root";
$password = "";
$db = "test";
$con = mysql_connect("localhost",$username,$password);
if (!$con)
die('Could not connect: ' . mysql_error());
mysql_select_db($db, $con);
$result = mysql_query("SELECT * FROM example ORDER BY date DESC");
while($row = mysql_fetch_assoc($result))
$output['qm'][]=$row;
print(json_encode($output));
mysql_close($con);
?>
LogCat:
12-24 10:19:54.322: E/AndroidRuntime(1700): FATAL EXCEPTION: main
12-24 10:19:54.322: E/AndroidRuntime(1700): android.os.NetworkOnMainThreadException
12-24 10:19:54.322: E/AndroidRuntime(1700): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1084)
12-24 10:19:54.322: E/AndroidRuntime(1700): at java.net.InetAddress.lookupHostByName(InetAddress.java:391)
12-24 10:19:54.322: E/AndroidRuntime(1700): at java.net.InetAddress.getAllByNameImpl(InetAddress.java:242)
12-24 10:19:54.322: E/AndroidRuntime(1700): at java.net.InetAddress.getAllByName(InetAddress.java:220)
12-24 10:19:54.322: E/AndroidRuntime(1700): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:137)
12-24 10:19:54.322: E/AndroidRuntime(1700): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
12-24 10:19:54.322: E/AndroidRuntime(1700): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
12-24 10:19:54.322: E/AndroidRuntime(1700): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
12-24 10:19:54.322: E/AndroidRuntime(1700): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
12-24 10:19:54.322: E/AndroidRuntime(1700): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
12-24 10:19:54.322: E/AndroidRuntime(1700): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
12-24 10:19:54.322: E/AndroidRuntime(1700): at com.qrodsintegrated.JSONParser.getJSONFromUrl(JSONParser.java:38)
12-24 10:19:54.322: E/AndroidRuntime(1700): at com.qrodsintegrated.QMFragment.<init>(QMFragment.java:41)
12-24 10:19:54.322: E/AndroidRuntime(1700): at com.qrodsintegrated.MainActivity.displayView(MainActivity.java:175)
12-24 10:19:54.322: E/AndroidRuntime(1700): at com.qrodsintegrated.MainActivity.access$0(MainActivity.java:164)
12-24 10:19:54.322: E/AndroidRuntime(1700): at com.qrodsintegrated.MainActivity$SlideMenuClickListener.onItemClick(MainActivity.java:126)
12-24 10:19:54.322: E/AndroidRuntime(1700): at android.widget.AdapterView.performItemClick(AdapterView.java:292)
12-24 10:19:54.322: E/AndroidRuntime(1700): at android.widget.AbsListView.performItemClick(AbsListView.java:1058)
12-24 10:19:54.322: E/AndroidRuntime(1700): at android.widget.AbsListView$PerformClick.run(AbsListView.java:2514)
12-24 10:19:54.322: E/AndroidRuntime(1700): at android.widget.AbsListView$1.run(AbsListView.java:3168)
12-24 10:19:54.322: E/AndroidRuntime(1700): at android.os.Handler.handleCallback(Handler.java:605)
12-24 10:19:54.322: E/AndroidRuntime(1700): at android.os.Handler.dispatchMessage(Handler.java:92)
12-24 10:19:54.322: E/AndroidRuntime(1700): at android.os.Looper.loop(Looper.java:137)
12-24 10:19:54.322: E/AndroidRuntime(1700): at android.app.ActivityThread.main(ActivityThread.java:4340)
12-24 10:19:54.322: E/AndroidRuntime(1700): at java.lang.reflect.Method.invokeNative(Native Method)
12-24 10:19:54.322: E/AndroidRuntime(1700): at java.lang.reflect.Method.invoke(Method.java:511)
12-24 10:19:54.322: E/AndroidRuntime(1700): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
12-24 10:19:54.322: E/AndroidRuntime(1700): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
12-24 10:19:54.322: E/AndroidRuntime(1700): at dalvik.system.NativeStart.main(Native Method)
【问题讨论】:
您需要检查您的调试日志并发布异常堆栈跟踪。 看来yoiu正在ui线程上运行网络相关操作。怀疑NetworkOnMainThreadException
。发布堆栈跟踪
那我该怎么办呢。让它工作?
使用Thread
或AsyncTask
你能用那个重写这个并帮助我吗,因为我用过一次,整个应用程序没有响应,数据没有被解析
【参考方案1】:
把这个写在你的 onCreate 中
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
对于 API 级别 >9
并且还使用异步任务来解析值
【讨论】:
不,不建议这样做。如果您正在测试,那么确定。所有与网络相关的操作都必须在后台线程中完成【参考方案2】:你有
JSONObject json = jParser.getJSONFromUrl(url);
在JSONParser
HttpResponse httpResponse = httpClient.execute(httpPost);
在 ui 线程上运行网络相关操作。
使用AsyncTask
或Thread
http://developer.android.com/reference/android/os/AsyncTask.html
new TheTask().execute(params);
然后
class TheTask extends AsyncTask<Void,Void,Void>
protected void doInbackground(Void... params)
// your http request
return null;
您可以将 asynctask 设置为 Fragment 的内部类并在onPostExecute
中更新 ui
编辑:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
View rootView = inflater.inflate(R.layout.fragment_qm, container, false);
new TheTask().execute(url);
return rootView;
然后
class TheTask extends AsyncTask<String,String,String>
@override
protected String doInbackground(String... params)
String _response =null;
try
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(params[0]);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
_response=EntityUtils.toString(httpEntity);
catch(Exception e)
e.printStacktrace();
return _response;
@Override
protected void onPostExecute(String result)
// TODO Auto-generated method stub
super.onPostExecute(result);
Log.i(".......",result);
【讨论】:
谢谢。我会照你说的做,然后回到你身边。 我现在明白了 12-24 11:07:04.802: W/dalvikvm(1848): threadid=1: 线程以未捕获的异常退出 (group=0x409961f8) 12-24 11:07:04.822 : E/AndroidRuntime(1848): FATAL EXCEPTION: main 12-24 11:07:04.822: E/AndroidRuntime(1848): java.lang.NullPointerException: println 需要消息 12-24 11:07:04.822: E/AndroidRuntime (1848): 在 android.util.Log.println_native(Native Method) 12-24 11:07:04.822: E/AndroidRuntime(1848): 在 android.util.Log.i(Log.java:159) 12-24 11:07:04.822: E/AndroidRuntime(1848): 在 com.qrodsintegrated.QMFragment$TheTask.onPostExecute(QMFragment.java:122) 12-24 11:07:04.822: E/AndroidRuntime(1848): 在 com.qrodsintegrated.QMFragment$TheTask.onPostExecute(QMFragment.java:1) 12-24 11:07:04.822: E/AndroidRuntime(1848): 在 android.os.AsyncTask.finish(AsyncTask .java:602) 12-24 11:07:04.822: E/AndroidRuntime(1848): 在 android.os.AsyncTask.access$600(AsyncTask.java:156) 12-24 11:07:04.822: E/AndroidRuntime( 1848): 在 android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:615) @Ruch1234 发布一个包含相关细节的新问题。我相信您的问题可以解决 @Ruch1234 因为这篇文章已经有一个公认的答案,所以进一步编辑它是不好的。新问题发布新问题。如果不是我,还有很多有才华的人,你的问题很快就会得到解决以上是关于在 Fragments 中使用 JSON 时,应用在 Android 开发中没有响应的主要内容,如果未能解决你的问题,请参考以下文章
我正在使用 Fragments,当我快速按下后退按钮时,应用程序崩溃了。它随机发生
将 ViewPager 与 Fragments 一起使用时,在滑动时会破坏 Fragment
使用 Fragments 和 ViewPager 一段时间后,Android 应用程序崩溃
在Fragments中保存和恢复ListView(livedata)