Android:使用处理程序但仍满足NetworkOnMainThreadException
我做一些网络方面的事情,我知道我不能在主线程上做。所以,我把它放进了Handler。这是我的密码:Android:使用处理程序但仍满足NetworkOnMainThreadException,android,handler,Android,Handler,我做一些网络方面的事情,我知道我不能在主线程上做。所以,我把它放进了Handler。这是我的密码: handler = new Handler(); handler.postDelayed(new OrderTask(this, url), 10 * 1000); // periodically run every 10 seconds. 这是我的Runnable类: public class OrderTask implements Runnable { OrderFragmen
handler = new Handler();
handler.postDelayed(new OrderTask(this, url), 10 * 1000); // periodically run every 10 seconds.
这是我的Runnable类:
public class OrderTask implements Runnable {
OrderFragment fragment;
String url;
public OrderTask(OrderFragment fragment, String url) {
this.fragment = fragment;
this.url = url;
}
@Override
public void run() {
synchronized (fragment.orders) {
fragment.orders = Order.loadServerOrders(url); // network code here
}
fragment.adapter.notifyDataSetChanged();
}
}
但当它运行时,它将在第loadSeverOrder
行抛出异常:NetworkOnMainThread
。我无法解释原因。请帮我想一想
谢谢:)处理程序将把
Runnable
发布到创建它的同一线程的消息队列中
您可以考虑在单独的线程中周期性地运行某些东西。
下面是这方面的代码示例:ScheduledExecutorService worker = Executors.newSingleThreadScheduledExecutor();
worker.scheduleAtFixedRate(new OrderTask(this, url),
0, //initial delay
10, //run every 10 seconds
TimeUnit.SECONDS);
请注意,如果您要在worker中更改UI元素,则需要在UI上下文中进行更改。为此,您可以使用处理程序
另一个选项是从继承您的OrderTask
。但这完全是另一回事处理程序将Runnable
发布到创建它的同一线程的消息队列中
您可以考虑在单独的线程中周期性地运行某些东西。
下面是这方面的代码示例:
ScheduledExecutorService worker = Executors.newSingleThreadScheduledExecutor();
worker.scheduleAtFixedRate(new OrderTask(this, url),
0, //initial delay
10, //run every 10 seconds
TimeUnit.SECONDS);
请注意,如果您要在worker中更改UI元素,则需要在UI上下文中进行更改。为此,您可以使用处理程序
另一个选项是从继承您的OrderTask
。但这完全是另一回事AHandler
将在创建代码的线程上执行代码。因此,如果handler=new handler()
正在您的UI线程上运行(很可能是这样),那么任何Runnable
都将在main上执行。@323go这真的是真的吗?我一直认为处理程序会自动添加新线程来运行工作。我认为为什么Handler是疯子,这是真的。“创建新处理程序时,它将绑定到正在创建它的线程的线程/消息队列”(来自处理程序文档)。处理程序的存在正是为了访问线程。如果你想要一个新的线程——创建一个<代码>线程读取=新线程(可运行)代码>我将建议您执行异步任务。更好地处理NetworkMainThread错误。对此类内容使用AsyncTask
或Intent Service
。处理程序将在创建它的线程上执行代码。因此,如果handler=new handler()
正在您的UI线程上运行(很可能是这样),那么任何Runnable
都将在main上执行。@323go这真的是真的吗?我一直认为处理程序会自动添加新线程来运行工作。我认为为什么Handler是疯子,这是真的。“创建新处理程序时,它将绑定到正在创建它的线程的线程/消息队列”(来自处理程序文档)。处理程序的存在正是为了访问线程。如果你想要一个新的线程——创建一个<代码>线程读取=新线程(可运行)代码>我将建议您执行异步任务。更好地处理NetworkMainThread错误。使用AsyncTask
或Intent Service
处理此类错误。谢谢:)但是,尽管我的活动/片段已关闭,但现在worker仍可以工作。我希望它与我的活动/片段同时关闭。我该怎么做?谢谢:)worker有shutdown()
方法。只需将worker.shutdown()
添加到活动的/fragment的onDestroy()
谢谢!例如,在创建Pavel编写的东西之前,您必须声明您的runnable并创建它runnable CADA5MinutesIncidencias=new runnable(){@Override public void run(){Log.d(Log_TAG_TAREAS,“Realizando incidencias”+getFechaHoraActual());ConnectionDetector cd=new ConnectionDetector(getApplicationContext());if(cd.isconnectedPointerNet()){String idioma=“es”;IncidenciasParser ip=new IncidenciasParser();mIncidencias=ip.parse(idioma);}};对于这个-ScheduledExecutorService或TimerTask,哪种方法更好?@JaydevKalivarapu TimerTask不会将工作卸载到后台线程。它只会安排它,所以您仍然需要创建单独的线程、使用AsyncTask或其他后台方法(谢谢:),但是,现在worker可以工作了,尽管我的活动/片段已经关闭。我希望它与我的活动/片段同时关闭。我该怎么做?谢谢:)worker有shutdown()
方法。只需将worker.shutdown()
添加到活动的/fragment的onDestroy()
谢谢!例如,在创建Pavel编写的东西之前,您必须声明您的runnable并创建它runnable CADA5MinutesIncidencias=new runnable(){@Override public void run(){Log.d(Log_TAG_TAREAS,“Realizando incidencias”+getFechaHoraActual());ConnectionDetector cd=new ConnectionDetector(getApplicationContext());if(cd.isconnectedPointerNet()){String idioma=“es”;IncidenciasParser ip=new IncidenciasParser();mIncidencias=ip.parse(idioma);}};对于这个-ScheduledExecutorService或TimerTask,哪种方法更好?@JaydevKalivarapu TimerTask不会将工作卸载到后台线程。它只是安排它,所以您仍然需要创建单独的线程、使用AsyncTask或其他类似的后台方法