Java Can';不要在线程内创建处理程序。如何使用Looper.prepare()?
可能重复:Java Can';不要在线程内创建处理程序。如何使用Looper.prepare()?,java,android,multithreading,service,Java,Android,Multithreading,Service,可能重复: 我正在开发一个Android服务,尝试每x次获取设备IP地址并将其与服务器通信。 我正在使用: Netbeans 7.2安卓SDK安卓谷歌Api 8SQLite 我知道有几个问题与这个问题有关,但没有一个能给我一个解决问题的方法。正如您在下面的代码中所看到的,我并没有尝试访问服务主线程的UI(我尝试了,但在我对行进行注释后,错误仍然保持不变)。另一方面,我正在使用AsyncTask,我认为这是一种合适的方法 这是我服务的主要部分: public class ArsosService
我正在开发一个Android服务,尝试每x次获取设备IP地址并将其与服务器通信。 我正在使用: Netbeans 7.2
安卓SDK
安卓谷歌Api 8
SQLite 我知道有几个问题与这个问题有关,但没有一个能给我一个解决问题的方法。正如您在下面的代码中所看到的,我并没有尝试访问服务主线程的UI(我尝试了,但在我对行进行注释后,错误仍然保持不变)。另一方面,我正在使用AsyncTask,我认为这是一种合适的方法 这是我服务的主要部分:
public class ArsosService extends Service {
private NotificationManager mNM;
private final Messenger mMessenger = new Messenger(new IncomingHandler());
protected DatabaseUtil dbu = null;
@Override
public void onCreate() {
mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
try {
dbu = DatabaseUtility.getInstance(this);
} catch (IOException ex) {
Log.e("Service", ex);
}
Timer timer = new Timer();
timer.schedule(new Checks(), 0, 15000);
}
private class Checks extends TimerTask {
@Override
public void run() {
CheckIpAddress_Task checkIp = new CheckIpAddress_Task();
checkIp.execute();
}
}
// Other methods
private class CheckIpAddress_Task extends AsyncTask<Void, Void, Integer> {
@Override
protected Integer doInBackground(Void... arg0) {
String ipLocal = getLocalIpAddress();
String text = null;
// ipLocal==null means there is no available connection, so we do nothing.
if (ipLocal != null) {
String ipDb = dbu.getLastIP(); // we get the IP saved in the DB.
if (ipDb == null) {
dbu.addProperty("IP", ipLocal); // we save the IP in the DB.
} else if (!ipLocal.equals(ipDb)) {
dbu.setProperty("IP", ipLocal); // we update the IP in the DB.
}
}
if (text != null) {
//showNotification(1, text, ipLocal);
}
return 0;
}
private String getLocalIpAddress() {
String result = null;
// Irrelevant code
return result;
}
}
}
公共类ArsosService扩展服务{
私人通知经理mNM;
专用最终信使mMessenger=新信使(新的IncomingHandler());
受保护的DatabaseUtil dbu=null;
@凌驾
public void onCreate(){
mNM=(NotificationManager)getSystemService(通知服务);
试一试{
dbu=DatabaseUtility.getInstance(这个);
}捕获(IOEX异常){
Log.e(“服务”,ex);
}
定时器=新定时器();
时间表(新检查(),0,15000);
}
私有类检查扩展了TimerTask{
@凌驾
公开募捐{
CheckIpAddress_Task checkIp=新的CheckIpAddress_Task();
checkIp.execute();
}
}
//其他方法
私有类CheckIpAddress_任务扩展了异步任务{
@凌驾
受保护的整数doInBackground(无效…arg0){
字符串ipLocal=getLocalIpAddress();
字符串文本=空;
//ipLocal==null意味着没有可用的连接,所以我们什么也不做。
if(ipLocal!=null){
String ipDb=dbu.getLastIP();//我们得到保存在数据库中的IP。
如果(ipDb==null){
addProperty(“IP”,ipLocal);//我们将IP保存在数据库中。
}else如果(!ipLocal.equals(ipDb)){
setProperty(“IP”,ipLocal);//我们更新数据库中的IP。
}
}
如果(文本!=null){
//showNotification(1,文本,ipLocal);
}
返回0;
}
私有字符串getLocalIpAddress(){
字符串结果=null;
//无关代码
返回结果;
}
}
}
我认为问题可能与线程有关,但我不知道在哪里。任何帮助都将不胜感激
编辑:虽然我已经接受了一个正确的答案,或者可能是因为它,但我一直在寻找更多关于它的信息。我遇到了一个问题,我想和你们大家分享,有一天你们需要更多地了解这个问题。它的作者Tejas Lagvankar以一种非常清晰易懂的方式解释了关于线程、循环器和处理程序的一切
-首先在类作用域中声明处理程序
对象引用变量
h代码>
-在onCreate()
方法中创建处理程序的实例
h=newhandler()代码>
-将其与以下线程一起使用:
new Thread(new Runnable(){
public void run(){
h.post(new Runnable(){
// Do the UI work here.
});
}
});
-您可以很好地使用android中提供的AsyncTask
,它被称为p*ainless threading.处理程序始终在Looper线程上下文中运行。当您声明一个单独的线程时,它的上下文与循环器不同。因此出现了错误
简单的解决方案总是在onCreate()、onStart()和onResume()中声明处理程序。如果您使用AsyncTasks,您可以很好地在onPreExecute()和onPostExecute()中声明处理程序,因为它们也在Looper上下文中运行。首先,很抱歉之前没有回答。谢谢你的时间和回答。我遵循了你的指示,效果很好。然而,我不确定这是否是一种非常正统的方法。我的方法现在看起来是这样的:私有类检查扩展了TimerTask{@Override public void run(){h.post(new Runnable(){public void run(){CheckIpAddress_Task checkIp=new CheckIpAddress_Task();checkIp.execute();}}}}正如我所说的,这个词是K,但它是正确的吗?谢谢你的回答。有了这些信息和Kumar Vivek Mitra的,我的问题得到了解决。