我只是编写一个可以使用JSON和PHP查询mysql数据库的简单程序,但即使我使用Async,我仍然在主线程异常上获得一个网络。
public class FetchActivity extends ActionBarActivity {
Button btnMushroom;
Button btnFlower;
Button btnStar;
String decription;
// Progress Dialog
private ProgressDialog pDialog;
// JSON parser class
JSONParser jsonParser = new JSONParser();
private static final String TAG_SUCCESS = "success";
private static final String TAG_PRODUCT = "product";
private static final String TAG_DECRIPTION = "decription";
private static final String url_get_image = "http://14.201.33.133/fetchfarmp /getUrl.php";
static String imageUrl = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fetch);
btnMushroom = (Button) findViewById(R.id.mushroom);
btnMushroom.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
decription = "Mario Mushroom";
new GetUrl().execute();
new DownloadImageTask((ImageView) findViewById(R.id.image_mario))
.execute(imageUrl);
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.fetch, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* Background Async Task to Get complete product details
* */
class GetUrl extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(FetchActivity.this);
pDialog.setMessage("Loading product details. Please wait...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
/**
* Getting product details in background thread
* */
protected String doInBackground(String... params) {
// updating UI from Background Thread
runOnUiThread(new Runnable() {
public void run() {
// Check for success tag
int success;
try {
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("decription", decription));
System.out.println("Attempting to run php ....");
// getting product details by making HTTP request
// Note that product details url will use GET request
JSONObject json = jsonParser.makeHttpRequest(
url_get_image, "GET", params);
System.out.println("json object Created!!!");
// check your log for json response
Log.d("Single Product Details", json.toString());
// json success tag
success = json.getInt(TAG_SUCCESS);
if (success == 1) {
System.out.println("Success I'm in!");
// successfully received product details
JSONArray productObj = json
.getJSONArray(TAG_PRODUCT); // JSON Array
// get first product object from JSON Array
JSONObject product = productObj.getJSONObject(0);
String imageUrl = product.getString("link");
}else{
// product with pid not found
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
return null;
}
}
}
我有一个类得到JSONParser来处理查询,并且假设从PHP代码返回一个JSONObject。我检查了PHP代码,它成功返回了一个JSONObject。 一旦我在JSONParser类中运行HTTPResponse,就会发生异常。我究竟做错了什么?
logcat的:
10-15 19:49:08.427: E/AndroidRuntime(21245): FATAL EXCEPTION: main
10-15 19:49:08.427: E/AndroidRuntime(21245): android.os.NetworkOnMainThreadException
10-15 19:49:08.427: E/AndroidRuntime(21245): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1144)
10-15 19:49:08.427: E/AndroidRuntime(21245): at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:84)
10-15 19:49:08.427: E/AndroidRuntime(21245): at libcore.io.IoBridge.connectErrno(IoBridge.java:127)
10-15 19:49:08.427: E/AndroidRuntime(21245): at libcore.io.IoBridge.connect(IoBridge.java:112)
10-15 19:49:08.427: E/AndroidRuntime(21245): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
10-15 19:49:08.427: E/AndroidRuntime(21245): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:459)
10-15 19:49:08.427: E/AndroidRuntime(21245): at java.net.Socket.connect(Socket.java:842)
10-15 19:49:08.427: E/AndroidRuntime(21245): at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:119)
10-15 19:49:08.427: E/AndroidRuntime(21245): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:144)
10-15 19:49:08.427: E/AndroidRuntime(21245): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
10-15 19:49:08.427: E/AndroidRuntime(21245): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
10-15 19:49:08.427: E/AndroidRuntime(21245): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
10-15 19:49:08.427: E/AndroidRuntime(21245): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:670)
10-15 19:49:08.427: E/AndroidRuntime(21245): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:509)
10-15 19:49:08.427: E/AndroidRuntime(21245): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
10-15 19:49:08.427: E/AndroidRuntime(21245): at com.example.fetchfarmtake9000.JSONParser.makeHttpRequest(JSONParser.java:67)
10-15 19:49:08.427: E/AndroidRuntime(21245): at com.example.fetchfarmtake9000.FetchActivity$GetUrl$1.run(FetchActivity.java:140)
10-15 19:49:08.427: E/AndroidRuntime(21245): at android.os.Handler.handleCallback(Handler.java:730)
10-15 19:49:08.427: E/AndroidRuntime(21245): at android.os.Handler.dispatchMessage(Handler.java:92)
10-15 19:49:08.427: E/AndroidRuntime(21245): at android.os.Looper.loop(Looper.java:137)
10-15 19:49:08.427: E/AndroidRuntime(21245): at android.app.ActivityThread.main(ActivityThread.java:5419)
10-15 19:49:08.427: E/AndroidRuntime(21245): at java.lang.reflect.Method.invokeNative(Native Method)
10-15 19:49:08.427: E/AndroidRuntime(21245): at java.lang.reflect.Method.invoke(Method.java:525)
10-15 19:49:08.427: E/AndroidRuntime(21245): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1187)
10-15 19:49:08.427: E/AndroidRuntime(21245): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
10-15 19:49:08.427: E/AndroidRuntime(21245): at dalvik.system.NativeStart.main(Native Method)
10-15 19:50:32.939: I/Process(21245): Sending signal. PID: 21245 SIG: 9
答案 0 :(得分:0)
为什么你在doInBackground()里面有这个:
runOnUiThread(new Runnable() {
...
}
? 这是工作代码应该没有任何发送到不同线程的地方。
它打破了你想要完成的一切。请参阅http://developer.android.com/reference/android/os/AsyncTask.html以了解如何实施后台任务。
/**
* Getting product details in background thread
* */
protected String doInBackground(String... params) {
// Check for success tag
int success;
try {
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("decription", decription));
System.out.println("Attempting to run php ....");
// getting product details by making HTTP request
// Note that product details url will use GET request
JSONObject json = jsonParser.makeHttpRequest(
url_get_image, "GET", params);
System.out.println("json object Created!!!");
// check your log for json response
Log.d("Single Product Details", json.toString());
// json success tag
success = json.getInt(TAG_SUCCESS);
if (success == 1) {
System.out.println("Success I'm in!");
// successfully received product details
JSONArray productObj = json
.getJSONArray(TAG_PRODUCT); // JSON Array
// get first product object from JSON Array
JSONObject product = productObj.getJSONObject(0);
return product.getString("link"); // imageUrl
}else{
// product with pid not found
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
return null;
}
protected void onPostExecute(String imageLink) {
// do here whatever you need on UiThread with link.
// but I suppose you should also download that image if not already fetched and return it as bitmap or something like it.
}
答案 1 :(得分:0)
问题是您实际上是在主线程上进行网络操作,这是不允许的。从runOnUiThread
移除doInBackground
,然后使用onPostExecute
和/或onProgressUpdate
来更新您的用户界面。您可以通过调用onProgressUpdate
将值从doInBackground
传递到publishProgress()
。有关详细信息,请参阅AsyncTask文档。