我已经在这个应用程序上工作了一段时间了,我即将完成,但是这个错误:
java.lang.RuntimeException: Unable to start activity ComponentInfo{org.marsfirst.mars_app/org.marsfirst.mars_app.TeamNews}: android.os.NetworkOnMainThreadException at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2413) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2471) at android.app.ActivityThread.access$900(ActivityThread.java:175) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1308) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:146) at android.app.ActivityThread.main(ActivityThread.java:5602) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099) at dalvik.system.NativeStart.main(Native Method) Caused by: android.os.NetworkOnMainThreadException at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1166) at com.android.org.conscrypt.OpenSSLSocketImpl.close(OpenSSLSocketImpl.java:1009) at org.apache.http.impl.SocketHttpClientConnection.close(SocketHttpClientConnection.java:205) at org.apache.http.impl.conn.DefaultClientConnection.close(DefaultClientConnection.java:161) at org.apache.http.impl.conn.tsccm.AbstractConnPool.closeConnection(AbstractConnPool.java:320) at org.apache.http.impl.conn.tsccm.AbstractConnPool.shutdown(AbstractConnPool.java:296) at org.apache.http.impl.conn.tsccm.ConnPoolByRoute.shutdown(ConnPoolByRoute.java:670) at org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager.shutdown(ThreadSafeClientConnManager.java:256) at com.parse.ParseRequest.initialize(ParseRequest.java:118) at com.parse.Parse.initialize(Parse.java:109) at org.marsfirst.mars_app.TeamNews.onCreate(TeamNews.java:41) at android.app.Activity.performCreate(Activity.java:5451) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1093) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2377)
在对这个问题进行了大量研究之后,我知道我需要将以下代码放入我的应用程序中:
AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
Parse.initialize(this, "Key",
"Key");;
}
};
但是我不确定将代码放在哪里。
我的MainPage.Java:
package org.marsfirst.mars_app;
import android.app.Activity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
public class MainPage extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mainpage);
ImageView website = (ImageView) findViewById(R.id.imageButton6);
website.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
new CallWebpage().execute();
}
});
ImageView logo1 = (ImageView) findViewById(R.id.imageButton7);
logo1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
new CallEvent().execute();
}
});
ImageView contactpage = (ImageView) findViewById(R.id.imagebutton8);
contactpage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
new CallContact().execute();
}
});
ImageView teamNews = (ImageView) findViewById(R.id.imagebutton1);
teamNews.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
new CallTeamNews().execute();
}
});
ImageView mechPage = (ImageView) findViewById(R.id.imageButton2);
mechPage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
new CallMechPage().execute();
}
});
ImageView driveNews = (ImageView) findViewById(R.id.imagebutton3);
driveNews.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
new CallDriveNews().execute();
}
});
ImageView oprPage = (ImageView) findViewById(R.id.imagebutton4);
oprPage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
new CallOprPage().execute();
}
});
ImageView ProgramingPage = (ImageView) findViewById(R.id.imagebutton5);
ProgramingPage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
new CallProgramingPage().execute();
}
});
ImageView food = (ImageView) findViewById(R.id.imageButton9);
food.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
new CallFood().execute();
}
});
ImageView travel = (ImageView) findViewById(R.id.imagebutton10);
travel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
new CallTravel().execute();
}
});
}
public class CallWebpage extends AsyncTask<Void, Void, String> {
protected String doInBackground(Void... urls) {
Intent intent = new Intent(MainPage.this, Webpage.class);
MainPage.this.startActivity(intent);
return "";
}
}
public class CallTeamNews extends AsyncTask<Void, Void, String> {
protected String doInBackground(Void... urls) {
Intent intent = new Intent(MainPage.this, TeamNews.class);
MainPage.this.startActivity(intent);
return "";
}
}
public class CallOprPage extends AsyncTask<Void, Void, String> {
protected String doInBackground(Void... urls) {
Intent intent = new Intent(MainPage.this, OprPage.class);
MainPage.this.startActivity(intent);
return "";
}
}
public class CallDriveNews extends AsyncTask<Void, Void, String> {
protected String doInBackground(Void... urls) {
Intent intent = new Intent(MainPage.this, DriveNews.class);
MainPage.this.startActivity(intent);
return "";
}
}
public class CallMechPage extends AsyncTask<Void, Void, String> {
protected String doInBackground(Void... urls) {
Intent intent = new Intent(MainPage.this, MechPage.class);
MainPage.this.startActivity(intent);
return "";
}
}
public class CallProgramingPage extends AsyncTask<Void, Void, String> {
protected String doInBackground(Void... urls) {
Intent intent = new Intent(MainPage.this, ProgramingPage.class);
MainPage.this.startActivity(intent);
return "";
}
}
public class CallEvent extends AsyncTask<Void, Void, String> {
protected String doInBackground(Void... urls) {
Intent intent = new Intent(MainPage.this, Event.class);
MainPage.this.startActivity(intent);
return "";
}
}
public class CallContact extends AsyncTask<Void, Void, String> {
protected String doInBackground(Void... urls) {
Intent intent = new Intent(MainPage.this, Contact.class);
MainPage.this.startActivity(intent);
return "";
}
}
public class CallFood extends AsyncTask<Void, Void, String> {
protected String doInBackground(Void... urls) {
Intent intent = new Intent(MainPage.this, Food.class);
MainPage.this.startActivity(intent);
return "";
}
}
public class CallTravel extends AsyncTask<Void, Void, String> {
protected String doInBackground(Void... urls) {
Intent intent = new Intent(MainPage.this, Travel.class);
MainPage.this.startActivity(intent);
return "";
}
}
}
Would I place the the code in somewhere like this:
public class CallProgramingPage extends AsyncTask<Void, Void, String> {
protected String doInBackground(Void... urls) {
Intent intent = new Intent(MainPage.this, ProgramingPage.class);
MainPage.this.startActivity(intent);
return "";
}
}
and if so how because when I did I received many errors.
However would it be better to set up an Async Task in my actual activity that uses parse:
package org.marsfirst.mars_app;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.StreamCorruptedException;
import android.app.Activity;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.parse.GetCallback;
import com.parse.Parse;
import com.parse.ParseException;
import com.parse.ParseObject;
import com.parse.ParseQuery;
public class TeamNews extends Activity {
private Context c;
private ParseProxyObject saved;
private TextView title, date, content;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Parse.initialize(this, "QmmXYAxVVSoT7MGlE3ZcAseCoLehfZko3BZJbo1P",
"SQHTLKcpNKDCLZWTgfOOFPEcmFYkdmWywKNProWG");
setContentView(R.layout.announcements);
c = getApplicationContext();
new CallUpdate(TeamNews.this).execute();
title = (TextView) findViewById(R.id.textView1);
date = (TextView) findViewById(R.id.textView2);
content = (TextView) findViewById(R.id.textView3);
saved = (ParseProxyObject) readObjectFromMemory("announce");
setTexts(saved);
if (title.getText().equals("Connect to internet and press refresh.")) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
@Override
public void onResume() {
super.onResume();
c = getApplicationContext();
if (isNetworkAvailable())
(new CallUpdate(TeamNews.this)).execute();
title = (TextView) findViewById(R.id.textView1);
date = (TextView) findViewById(R.id.textView2);
content = (TextView) findViewById(R.id.textView3);
saved = (ParseProxyObject) readObjectFromMemory("announce");
setTexts(saved);
}
public void setTexts(ParseProxyObject saved) {
if (saved == null) {
emptyTexts();
title.setText("Connect to internet and press refresh.");
return;
}
String format = "\t";
title.setText(format + saved.getString("name"));
String format2 = "\t";
date.setText(format2 + saved.getString("date_updated"));
String format3 = "\t";
content.setText(format3 + saved.getString("content_1"));
}
public ParseProxyObject readObjectFromMemory(String filename) {
FileInputStream fis;
ParseProxyObject object = null;
try {
fis = openFileInput(filename);
ObjectInputStream is = new ObjectInputStream(fis);
object = (ParseProxyObject) is.readObject();
is.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (StreamCorruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return object;
}
public void emptyTexts() {
title.setText("");
date.setText("");
content.setText("");
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu items for use in the action bar
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle presses on the action bar items
switch (item.getItemId()) {
case R.id.action_refresh_k:
(new CallUpdate(c)).execute();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
public class CallUpdate extends AsyncTask<Void, Void, String> {
private Context c;
public CallUpdate(Context newC) {
c = newC;
}
@Override
protected void onPreExecute() {
View v = findViewById(R.id.action_refresh_k);
if (v != null)
v.setVisibility(View.GONE);
}
protected String doInBackground(Void... urls) {
ParseQuery<ParseObject> query;
saved = (ParseProxyObject) readObjectFromMemory("announce");
query = ParseQuery.getQuery("Announcements");
query.getInBackground("1XLhLinldW", new GetCallback<ParseObject>() {
public void done(ParseObject object, ParseException e) {
if (e == null) {
if (object != null
&& (saved == null || !(object.getInt("version") == saved
.getInt("version")))) {
saved = new ParseProxyObject(object);
(new CallSave(c, saved, "announce")).execute();
}
} else {
// something went wrong
return;
}
}
});
return "";
}
protected void onPostExecute(String result) {
View v = findViewById(R.id.action_refresh_k);
if (v != null)
v.setVisibility(View.VISIBLE);
saved = (ParseProxyObject) readObjectFromMemory("announce");
setTexts(saved);
}
}
public void writeObjectToMemory(String filename, ParseProxyObject object) {
FileOutputStream fos;
try {
fos = c.openFileOutput(filename, Context.MODE_PRIVATE);
ObjectOutputStream os = new ObjectOutputStream(fos);
os.writeObject(object);
os.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void makeToast(String text) {
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(c, text, duration);
toast.show();
}
public class CallSave extends AsyncTask<Void, Void, String> {
Context c;
ParseProxyObject object;
String filename;
public CallSave(Context newC, ParseProxyObject newObject,
String newFileName) {
c = newC;
object = newObject;
filename = newFileName;
}
@Override
protected void onPreExecute() {
}
@Override
protected String doInBackground(Void... urls) {
FileOutputStream fos;
try {
fos = openFileOutput(filename, Context.MODE_PRIVATE);
ObjectOutputStream os = new ObjectOutputStream(fos);
os.writeObject(((ParseProxyObject) object));
os.flush();
os.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
@Override
protected void onPostExecute(String result) {
}
}
private boolean isNetworkAvailable() {
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager
.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
}
请帮助我,我完全迷失了,我不知道还能把它放在哪里,如果我的代码风格错误,请告诉我。我仍在学习和自学,所以请原谅我的白痴。 谢谢。
最佳答案
您需要将所有网络代码放入 DoInBackground 方法中。有四种方法可用于 async onPreExecute,它在 UiThread 上运行,并在进入 doInBackgound 之前执行您想要的所有更新。 doInBackground 会在 UI 线程之外完成所有工作,并且您不会在 mainThread 上获得网络异常。一旦 doinbackground 完成,onPostExecute 就会被调用,您可以显示结果并更新 UI,因为 onPostExecute 在 UIThread 上运行,并且还有一些其他可用的,如 oncanceled 等。
AsyncTask 可以正确且轻松地使用 UI 线程。此类允许在 UI 线程上执行后台操作并发布结果,而无需操作线程和/或处理程序。
AsyncTask 被设计为围绕 Thread 和 Handler 的辅助类,并不构成通用的线程框架。 AsyncTasks 理想情况下应该用于短操作(最多几秒钟)。如果您需要保持线程长时间运行,强烈建议您使用 java.util.concurrent pacakge 提供的各种 API,例如Executor、ThreadPoolExecutor 和 FutureTask。
异步任务由在后台线程上运行的计算定义,其结果在 UI 线程上发布。异步任务由 3 个通用类型(称为 Params、Progress 和 Result)和 4 个步骤(称为 onPreExecute、doInBackground、onProgressUpdate 和 onPostExecute)定义。
您可以查看这些帖子,它们是很好的 AsyncTasks 示例,您的所有困惑都会得到解决:)
http://www.vogella.com/tutorials/AndroidBackgroundProcessing/article.html
http://android.programmerguru.com/android-asynctask-example/
了解更多信息。
http://developer.android.com/reference/android/os/AsyncTask.html
关于java - 网络错误和异步困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24987566/