我在我的第一个活动中使用AsyncTask类,它的工作正常 并调用第二个,我在onCreate中调用另一个AsyncTask调用对象 并在doInBackground中调用webservice 然后它给予例外 android.os.networkmainthread。
我不知道如何 我是Android开发的新手 所以请给我看一些样品,或者我给你看我的代码
这是我的代码
public class panel extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.panel);
User_Balance_Load Balance_load=new User_Balance_Load();
Balance_load.execute();
Toast.makeText(getBaseContext(),Cls_Constant.username, Toast.LENGTH_LONG).show();
}
class User_Balance_Load extends AsyncTask<Void, Void, Void>
{
private final ProgressDialog dialog = new ProgressDialog(panel.this);
protected void onPreExecute() {
this.dialog.setMessage("Loding Diet type...");
this.dialog.show();
}
protected Void doInBackground(final Void... unused) {
// TODO Auto-generated method stub
panel.this.runOnUiThread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
Update_balance();
}
});
return null;
}
protected void onPostExecute(Void result)
{
if (this.dialog.isShowing())
{
this.dialog.dismiss();
}
}
}
void Update_balance()
{
Vector result;
result=Cls_webservice.User_Balance(Cls_Constant.Guid);
if(result.size()>0)
{
String UserBalance=result.elementAt(2).toString();
TextView Tv_User_balacne=(TextView)findViewById(R.id.tv_point_balance);
Tv_User_balacne.setText(UserBalance);
}
}
这是我的webservice类
public class Cls_webservice {
public static Vector User_Balance(String id)
{
Vector _vector = new Vector();
final String userid = id;
final String METHOD_NAME = "WCFDatatableRes";
final String SOAP_ACTION = "http://tempuri.org/WCFDatatableRes";
final String NAMESPACE = "http://tempuri.org/";
final String URL = "http://xxxxxxxx.com/GameRoom/ANDROIDLOTT/WebService.asmx";
String return_val="";
SoapObject newob;
try
{
Object response;
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.encodingStyle = SoapEnvelope.ENC;
SoapObject Request = new SoapObject(NAMESPACE , METHOD_NAME);
Request.addProperty("Params", userid+",3");
Request.addProperty("Do", "Balance");
envelope.dotNet = true;
envelope.setOutputSoapObject(Request);
AndroidHttpTransport httptransport ;
httptransport = new AndroidHttpTransport(URL);
httptransport.debug=true;
try
{
httptransport.call(SOAP_ACTION,envelope);
response = envelope.getResponse();
newob = (SoapObject)envelope.bodyIn;
return_val = newob.toString();
SoapObject diettype_listResult = (SoapObject) newob.getProperty("WCFDatatableRes ") ;
SoapObject diffgram = (SoapObject) diettype_listResult.getProperty("diffgram") ;
}
catch (Exception e) {
System.out.println("error:" + e);
}
}
catch (Exception e) {
}
return _vector;
}
}
此行中有例外 - &gt; “httptransport.call(SOAP_ACTION,信封); 所以请帮帮我 而这个相同的代码工作 我的第一个活动 我不知道为什么在第二次出现错误 感谢
答案 0 :(得分:1)
NetworkOnMainThread发生异常,因为您正在UI线程上运行与网络相关的操作。仅针对Honeycomb SDK或更高版本的应用程序进行此操作。针对早期SDK版本的应用程序可以在其主要事件循环线程上进行网络连接,但是非常不鼓励这样做。请参阅文档设计响应性。
您正在使用runonUithread运行Update_balance()。
您正在尝试通过调用Update_balance()来更新doInBackground()中的ui,该文件在textview中设置文本如下所示。你不应该在doInBackground()中更新ui。
TextView Tv_User_balacne=(TextView)findViewById(R.id.tv_point_balance);
Tv_User_balacne.setText(UserBalance);TextView Tv_User_balacne=(TextView)findViewById(R.id.tv_point_balance);
Tv_User_balacne.setText(UserBalance);
所有与网络相关的操作都应该在doInBackground()中完成。在doInBackground()中进行web服务调用。
您可以从doInBackground()
返回onPostExecute()
中的值,然后相应地更新ui。
class TheTask extends AsyncTask<Void,Void,Void>
{
protected void onPreExecute()
{ super.onPreExecute();
//display progressdialog.
}
protected void doInBackground(Void ...params)//return result here
{
//http request. do not update ui here
//call webservice
//return result here
return null;
}
protected void onPostExecute(Void result)//result of doInBackground is passed a parameter
{
super.onPostExecute(result);
//dismiss progressdialog.
//update ui using the result returned form doInbackground()
}
}
这4个步骤 执行异步任务时,任务将执行4个步骤:
onPreExecute(),在执行任务之前在UI线程上调用。此步骤通常用于设置任务,例如通过在用户界面中显示进度条。
doInBackground(Params ...),在onPreExecute()完成执行后立即在后台线程上调用。此步骤用于执行可能需要很长时间的后台计算。异步任务的参数将传递给此步骤。计算结果必须由此步骤返回,并将传递回最后一步。此步骤还可以使用publishProgress(Progress ...)发布一个或多个进度单元。这些值发布在UI线程的onProgressUpdate(Progress ...)步骤中。
onProgressUpdate(Progress ...),在调用publishProgress(Progress ...)后在UI线程上调用。执行的时间是不确定的。此方法用于在后台计算仍在执行时显示用户界面中的任何形式的进度。例如,它可用于为进度条设置动画或在文本字段中显示日志。
onPostExecute(Result),在后台计算完成后在UI线程上调用。背景计算的结果作为参数传递给此步骤。
有关详细信息,请查看以下链接
http://developer.android.com/reference/android/os/AsyncTask.html
答案 1 :(得分:0)
你正在使用asynctask,然后在你的asynctask中,你在UI线程下运行代码。这是无稽之谈,因为结果与在OnCreate()方法上执行代码相同。
protected Void doInBackground(final Void... unused)
{
Vector result = Update_balance();
panel.this.runOnUiThread(new Runnable()
{
@Override
public void run()
{
if(result.size()>0)
{
String UserBalance=result.elementAt(2).toString();
TextView Tv_User_balacne=(TextView)findViewById(R.id.tv_point_balance);
Tv_User_balacne.setText(UserBalance);
}
}
});
return null;
}
Vector Update_balance()
{
Vector result;
result=Cls_webservice.User_Balance(Cls_Constant.Guid);
return result;
}