LocationFragment类:
public class LocationFragment extends Fragment {
FragmentNameFactory nameFactory = new FragmentNameFactory();
List<LocationData> locationData;
LocationRecyclerAdapter locationRecyclerAdapter = new LocationRecyclerAdapter(locationData);
public LocationFragment(){
//Fragment needs a constructor, can be empty
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
((MainActivity) getActivity()).setFragmentName(nameFactory.getNameNL(6));
final View view = inflater.inflate(R.layout.flocationrecylce, container, false);
new JSONAsyncTask(new JSONCallBack(){
//This method updates the UI
@Override
public void success(JSONParser jsonParser) {
final JSONParser json = jsonParser;
//This part makes sure it is able to multi thread.
//In case this method is missing the application will crash upon refreshing this fragment
locationData = json.storeJSONData();
RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.locationRecyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setAdapter(locationRecyclerAdapter);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(linearLayoutManager);
}
//In case of failure the method sprints the log to the debugging console
@Override
public void failed() {
System.out.print("Failure");
}
//Sends the task to the doInBackground method inside RSSReaderAsync, which execute the code inside RSSReader
}).execute("");
return view;
}
@Override
public void onViewCreated(View view, Bundle savedInstance){
super.onViewCreated(view, savedInstance);
}
@Override
public void onActivityCreated(Bundle savedInstance){
super.onActivityCreated(savedInstance);
}
}
JSONParser类:
public class JSONParser {
String url;
String requestMethod;
List<LocationData> locations;
public JSONParser(String url, String requestMethod){
this.url = url;
this.requestMethod = requestMethod;
locations = storeJSONData();
}
private String read(BufferedReader bufferedReader) throws IOException {
//Creates new StringBuilder to avoid escaping chars
StringBuilder stringBuilder = new StringBuilder();
//Creates new variable
String currentLine;
//Gets the currentLine
while((currentLine = bufferedReader.readLine()) !=null ){
//Adds the currentLine to the stringBuild if the currentLine is not null
stringBuilder.append(currentLine);
}
//Returns the StringBuilder is String format
return stringBuilder.toString();
}
public JSONObject sendRequest() throws IOException, JSONException {
//Get the URL from the constructor
URL url = new URL(this.url);
//Opens the connection
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
//Sets the requestMethod
connection.setRequestMethod(this.requestMethod);
//Sets the requestProperties
connection.setRequestProperty("Content-type", "application/JSON");
//Tries to read the through the BufferedReader
try {
//Creates new BufferedReader & InputStreamReader which get the input of the connection
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
//Stores the output of the connection in a string
String jsonText = read(bufferedReader);
//Creates a new JSON object from the above String
JSONObject json = new JSONObject(jsonText);
//Returns the JSON Object
return json;
} finally {
//Disconnects from the URL
connection.disconnect();
}
}
public List<LocationData> storeJSONData(){
//Creates temporary List
List<LocationData> tempList = new ArrayList<>();
try{
//Sends request
JSONObject json = sendRequest();
//For loop to parse all the data from the request
for(Integer i =0; i < json.getJSONArray("response").length(); i++){
tempList.add(new LocationData(json.getJSONArray("response").getJSONObject(i).getString("name"),
json.getJSONArray("response").getJSONObject(i).getString("zipcode"),
json.getJSONArray("response").getJSONObject(i).getString("street"),
json.getJSONArray("response").getJSONObject(i).getString("streetnumber"),
json.getJSONArray("response").getJSONObject(i).getDouble("longitude"),
json.getJSONArray("response").getJSONObject(i).getDouble("latitude"),
json.getJSONArray("response").getJSONObject(i).getString("city")));
}
}
catch (IOException e){
System.out.print(e);
}
catch (JSONException e){
System.out.print(e);
}
//Returns the list
return tempList;
}
}
JSONCallBack界面:
public interface JSONCallBack {
void success(JSONParser jsonParser);
void failed();
}
JSONAsyncTask类:
public class JSONAsyncTask extends AsyncTask<String, Integer, Integer> {
private JSONCallBack jsonCallBack;
public JSONAsyncTask(JSONCallBack jsonCallBack) {
this.jsonCallBack = jsonCallBack;
}
@Override
protected Integer doInBackground(String... params) {
JSONParser parser = new JSONParser("http://grwn.ddns.net:1337/locations", "POST");
jsonCallBack.success(parser);
return null;
}
}
我试图在片段中创建异步任务。我这样做的方式适用于我的RSS阅读器,但不知怎的,它对我的JSONParser不起作用。我几乎尝试了这个主题的每个答案How to fix android.os.NetworkOnMainThreadException?
这些选项都没有解决我的问题:
android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1303)
at java.net.SocketInputStream.read(SocketInputStream.java:150)
at java.net.SocketInputStream.read(SocketInputStream.java:120)
at com.android.okhttp.okio.Okio$2.read(Okio.java:136)
at com.android.okhttp.okio.AsyncTimeout$2.read(AsyncTimeout.java:211)
at com.android.okhttp.okio.RealBufferedSource.exhausted(RealBufferedSource.java:60)
at com.android.okhttp.internal.http.HttpConnection.isReadable(HttpConnection.java:155)
at com.android.okhttp.Connection.isReadable(Connection.java:417)
at com.android.okhttp.OkHttpClient$1.isReadable(OkHttpClient.java:93)
at com.android.okhttp.internal.http.HttpEngine.createNextConnection(HttpEngine.java:339)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:329)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:247)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:457)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:405)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:243)
at com.example.sande.androidhro.JSONParser.sendRequest(JSONParser.java:69)
at com.example.sande.androidhro.JSONParser.storeJSONData(JSONParser.java:92)
at com.example.sande.androidhro.LocationFragment$1$1.run(LocationFragment.java:46)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:153)
at android.app.ActivityThread.main(ActivityThread.java:6236)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:891)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:781)
我知道这与Async任务有关,但我不知道我做错了什么
答案 0 :(得分:1)
sendRequest()函数必须在后台发生(也就是asynctask中的doinbackground)
所有这些都是因为你需要在反向线程上进行网络调用,
话虽如此,您可以使用Volley或Retrofit Libraries来简化网络电话
排球 - https://developer.android.com/training/volley/index.html
改造 - http://square.github.io/retrofit/
编辑:
这是你的成功:
@Override
public void success(JSONParser jsonParser) {
final JSONParser json = jsonParser;
**locationData = json.storeJSONData();**
RecyclerView recyclerView = (RecyclerView)
view.findViewById(R.id.locationRecyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setAdapter(locationRecyclerAdapter);
LinearLayoutManager linearLayoutManager = new
LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(linearLayoutManager);
您现在正在使用mainthread(这就是为什么您可以更改视图并执行findviewbyid等等...)
比你尝试
locationData = json.storeJSONData();
再次调用sendrequest,这次是在mainthread上,就像Slevin试图暗示的那样,这将解决当前的崩溃问题。