我正在学习如何构建Android应用,并尝试使用Java在我的数据库中插入数据。
但我没有成功,我收到了这个错误:
android.os.NetworkOnMainThreadException
我对此进行了更多搜索,并且每个人都说AsynkTask
删除了此错误。如何使我的代码适应AsynkTask
?你能解释一下它是如何运作的吗?
由于
代码
package com.example.turanja;
....
public class register extends Activity {
String name;
String id;
InputStream is=null;
String result=null;
String line=null;
int code;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.register);
final EditText e_id=(EditText) findViewById(R.id.editText1);
final EditText e_name=(EditText) findViewById(R.id.editText2);
Button insert=(Button) findViewById(R.id.button1);
insert.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
id = e_id.getText().toString();
name = e_name.getText().toString();
insert();
}
});
}
public void insert()
{
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("id",id));
nameValuePairs.add(new BasicNameValuePair("name",name));
try
{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://10.0.2.2/example/insert.php");
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
Log.e("pass 1", "connection success ");
}
catch(Exception e)
{
Log.e("Fail 1", e.toString());
Toast.makeText(getApplicationContext(), "Invalid IP Address",
Toast.LENGTH_LONG).show();
}
try
{
BufferedReader reader = new BufferedReader
(new InputStreamReader(is,"iso-8859-1"),8);
StringBuilder sb = new StringBuilder();
while ((line = reader.readLine()) != null)
{
sb.append(line + "\n");
}
is.close();
result = sb.toString();
Log.e("pass 2", "connection success ");
}
catch(Exception e)
{
Log.e("Fail 2", e.toString());
}
try
{
JSONObject json_data = new JSONObject(result);
code=(json_data.getInt("code"));
if(code==1)
{
Toast.makeText(getBaseContext(), "Inserted Successfully",
Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(getBaseContext(), "Sorry, Try Again",
Toast.LENGTH_LONG).show();
}
}
catch(Exception e)
{
Log.e("Fail 3", e.toString());
}
}
}
答案 0 :(得分:0)
请在此处查看answer。它会显示一个类似
的流程图
记住这一点..i将向您展示如何在您的代码中执行此操作。
创建一个扩展AsyncTask
的新类,如..
private class MyTask extends AsyncTask<String, Integer, String> {
// Runs in UI before background thread is called
@Override
protected void onPreExecute() {
super.onPreExecute();
// Do something like display a progress bar
}
// This is run in a background thread
@Override
protected String doInBackground(String... params) {
String msg="";
ArrayList<NameValuePair> nameValuePairs = new
ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("id",id));
nameValuePairs.add(new BasicNameValuePair("name",name));
try
{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://10.0.2.2/example/insert.php");
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
Log.e("pass 1", "connection success ");
}
catch(Exception e)
{
Log.e("Fail 1", e.toString());
msg="Invalid IP Address";
}
try
{
BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
StringBuilder sb = new StringBuilder();
while ((line = reader.readLine()) != null)
{
sb.append(line + "\n");
}
is.close();
result = sb.toString();
Log.e("pass 2", "connection success ");
}
catch(Exception e)
{
Log.e("Fail 2", e.toString());
}
try
{
JSONObject json_data = new JSONObject(result);
code=(json_data.getInt("code"));
if(code==1)
{
msg="Inserted Successfully";
}
else
{
msg="Sorry, Try Again";
}
}
catch(Exception e)
{
Log.e("Fail 3", e.toString());
}
}
return msg;
}
// This runs in UI when background thread finishes
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
// Do things like hide the progress bar or change a TextView
Toast.makeText(getBaseContext(),result,Toast.LENGTH_LONG).show();
}
}
并添加new MyTask().execute();
,而不是调用insert();
。我已将您在insert()
中完成的所有操作移至doInBackground()
。
答案 1 :(得分:0)
当您尝试执行主UI线程的网络操作时,会发生此异常。
有关例外的详情 -
当应用程序尝试在其主线程上执行网络操作时引发的异常。
仅针对Honeycomb SDK或更高版本的应用程序进行此操作。针对早期SDK版本的应用程序可以在其主要事件循环线程上进行联网,但是非常不鼓励。
尝试在AsyncTask中执行相同操作。示例代码段看起来像 -
class InsertTask extends AsyncTask<String, Integer, HttpEntity> {
protected HttpEntity doInBackground(String... data) {
try {
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("id",data[0]));
nameValuePairs.add(new BasicNameValuePair("name",data[1]));
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://10.0.2.2/example/insert.php");
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
return entity;
} catch (Exception e) {
//log exception
return null;
}
}
protected void onPostExecute(HttpEntity id) {
//further processing
//perhaps callback to main activity for success/failure
}
}
您可以将此AsyncTask执行为
new InsertTask().execute(dataToInsert);
答案 2 :(得分:0)
我更喜欢将服务用于此类工作,因为asyntask几乎没有限制。请参考此链接: “重新启动Activity时,AsyncTask对Activity的引用无效,因此onPostExecute()对新Activity没有任何影响。” http://blog.danlew.net/2014/06/21/the-hidden-pitfalls-of-asynctask/