2011-12-15 77 views
0

我有一个运行2个线程的应用程序。第一个是以1秒为间隔更新图形,第二个是以60秒间隔更新另一个图形。第二项任务需要很长时间,因为它在互联网上查询某个服务器3次,可能并不总是可用,即使这样做需要5到7秒才能执行。Android - 为什么第二个线程停止执行第一个线程?

发生了什么事情是当我启动第二个线程时,它会暂停第一个线程的执行,而这不是我想要的,我希望两者都同时运行。在Youtube视频中,您可以看到正在运行的应用程序的结果。 http://youtu.be/l7K5zSWzlxI “thread_updater1s”正在角落里运行一个绿色图形,大量读数和一个计时器,所以你清楚地看到它停顿了11秒。

1)首先,为什么会发生这种情况?如何解决它?

2)我知道我可能不会正确启动线程。我很难理解如何使某些东西在Java中以间隔循环运行,并且我的代码对于一个图形/花纹可以很好地工作。现在,当我在单独的线程中有2个循环时,我不知道它们为什么不同时执行。

下面是代码:

public class LoopExampleActivity extends Activity { 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    this.requestWindowFeature(Window.FEATURE_NO_TITLE); 
    setContentView(R.layout.main); 
    thread_updater1s.start(); 
    thread_updater2.start(); 
}// end of onCreate 

final Runnable r1s = new Runnable() { 
    public void run() { 
     do_1s_updates(); // those are very quick http calls to the local API server 
    }     // to get data nessessary for some plot. 
         // They have 1s timeout as well but rarely timeout 
}; 

final Runnable r2 = new Runnable() { 
    public void run() { 
     do_large_updates(); //This makes 7 long call over the Internet to the slow https 
          //server once every 60s. Has 10s timeout and sometimes takes as much as 
          //7s to execute 
     } 
}; 

Thread thread_updater1s = new Thread() { 
    @Override 
    public void run() { 
     try { 
      while (true) { 
       handler.post(r1s); 
       sleep(1000); 
      } 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
}; 

Thread thread_updater2 = new Thread() { 
    @Override 
    public void run() { 
     try { 
      while (true) { 
       handler2.post(r2); 
       sleep(60000); 
      } 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
}; 

}

PS。请原谅和翔实的我只有Java代码15天迄今没有任何事先经验或教训。

回答

0

您需要在线程中发出http请求(不是发布的runnables)。然后,当您下载数据时,您将使用该数据创建一个可运行的数据,该数据将更新图形并将其发布为可由UI线程执行的可运行数据。下面是一个示例:

public class LoopExampleActivity extends Activity { 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    this.requestWindowFeature(Window.FEATURE_NO_TITLE); 
    setContentView(R.layout.main); 
    thread_updater1s.start(); 
    thread_updater2.start(); 
}// end of onCreate 

Thread thread_updater1s = new Thread() { 
    @Override 
    public void run() { 
     try { 
      while (true) { 
       final Object data = getDataFromServer1(); 
       handler.post(new Runnable() { 
        @Override 
        public void run() { 
         updateGraph1(data); 
        } 
       ); 
       sleep(1000); 
      } 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
}; 

Thread thread_updater2 = new Thread() { 
    @Override 
    public void run() { 
     try { 
      while (true) { 
       final Object data = getDataFromServer2(); 
       handler.post(new Runnable() { 
        @Override 
        public void run() { 
         updateGraph2(data); 
        } 
       ); 
       sleep(60000); 
      } 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
}; 

显然,通过表示您的数据的适当类更改最终对象数据。

0

handler.post将runnable推送到主(UI)线程的消息队列中,以便在主线程上执行。

所以你在做什么是每个睡眠间隔,你发送消息到主线程运行该功能。显然,主线程不能同时运行两件事,所以这就是为什么一个runnable会延迟下一个runnable的原因。

您可能想要在单独的线程中执行runnable的工作 - 您为什么开始使用处理程序?如果您直接拨打do_1s_updatesdo_large_updates而不是通过处理程序&可运行,会发生什么情况?

+0

谢谢,这是一个大开眼界!不知道处理程序发布到主UI。但是,我怎样才能使线程循环出来,我可以做thread_updater1s.post()在结束做出一个循环吗? – 2011-12-15 21:38:59

+0

我使用了处理程序,因为这是我在网上找到的第一个例子,可以轻松地停下来做一个循环。我看到还有HandlerThread就是我需要的,所以我不需要改变我的应用程序呢? – 2011-12-15 22:13:08

相关问题