我有一个连接到Web服务并读取最新数据的类。它是:
public class LatestProductsReader extends Thread {
private String mResponse = "";
class SoapLatestProduct extends SoapConnector {
public SoapLatestProduct(String web_service_address) {
super("GetLatestParts", web_service_address);
}
}
public void run() {
String url = "my_web_service_address";
try {
SoapLatestProduct latestProduct = new SoapLatestProduct(url);
mResponse = latestProduct.call();
} catch (Exception ex) {
ex.printStackTrace();
}
}
public String getResponse() {
return mResponse;
}
}
我希望每10分钟从一个服务调用这个类的实例。我在下面写了代码,但总是以NetworkOnMainThreadException结束。问题是什么?
public class SynchronizerService extends Service implements {
// .
// .
// .
private Timer mTimer=null; // timer handling
private Handler mHandler = new Handler();
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flag, int startId) {
Runnable runnable = new Runnable() {
public void run() {
mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(),
0,
TICK_INTERVAL);
}
};
Thread t = new Thread(runnable);
t.run();
return START_STICKY;
}
@Override
public void onCreate() {
// cancel if service is already existed
if(mTimer!=null)
mTimer.cancel();
else
mTimer=new Timer(); // recreate new timer
}
@Override
public void onDestroy() {
Toast.makeText(this, "In Destroy", Toast.LENGTH_SHORT).show();//display toast when method called
mTimer.cancel();//cancel the timer
}
private class TimeDisplayTimerTask extends TimerTask {
@Override
public void run() {
// run on another thread
mHandler.post(new Runnable() {
@Override
public void run() {
try {
// display toast at every tick
LatestProductsReader PartCallert = new LatestProductsReader();
PartCallert.run();
PartCallert.join();
PartCallert.start();
while(PartCallert.getResponse() == null || PartCallert.getResponse().isEmpty()){
Thread.sleep(10);
}
String res = PartCallert.getResponse();
Toast.makeText(getApplicationContext(), res , Toast.LENGTH_SHORT).show();
}
catch (Exception ex){
ex.printStackTrace();
}
}
});
}
}
}
先谢谢。
答案 0 :(得分:0)
当应用程序尝试在其主线程上执行网络操作时,抛出此异常。在AsyncTask中运行代码。
答案 1 :(得分:0)
我将这个答案发布给未来的读者。虽然它可以用不同的方法解决,但这个解决了我的问题。我从 AsyncTask 继承了每个 Reader 类,并为每个类创建了一个观察者接口,以通知用户类(SyncronizerService)。示例类如下:
public class LatestCustomersReader extends AsyncTask<Void, Void, String> {
private SoapLatestCustomer reader = null;
private OnCustomerChangeListener mListener;
public interface OnCustomerChangeListener {
void customerAdded(Customer customer);
}
public class SoapLatestCustomer extends SoapConnector {
public SoapLatestCustomer(String web_service_address) {
super("GetLatestCustomers", web_service_address);
}
}
public LatestCustomersReader(OnCustomerChangeListener listener){
mListener = listener;
}
@Override
protected String doInBackground(Void... params){
// Do my stuff
SoapLatestCustomer reader = new SoapLatestCustomer(url);
String response = reader.call();
return response
}
// other AsynTask methods
}
用户类:
public class SynchronizerService extends Service implements
LatestCustomersReader.OnCustomerChangeListener {
@Override
public int onStartCommand(Intent intent, int flag, int startId) {
Runnable runnable = new Runnable() {
public void run() {
mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(),
0,
/*TICK_INTERVAL*/10000);
}
};
Thread t = new Thread(runnable);
t.run();
return START_STICKY;
}
@Override
public void customerAdded(Customer customer) {
// Insert to DB or whatever you want
}
private class TimeDisplayTimerTask extends TimerTask {
@Override
public void run() {
mHandler.post(new Runnable() {
@Override
public void run() {
try {
getProducts(); // Uses ProductReader
getCustomers(); // Uses LatestCustomerReader
//
// ...
//
} catch (Exception ex) {
ex.printStackTrace();
}
}
});
}
我希望它有用。 } }