【问题标题】:Android MapActivity thread questionAndroid MapActivity 线程问题
【发布时间】:2010-10-01 14:21:20
【问题描述】:

如何确保代码在 Android MapActivity 项目的 UI 线程上执行或不执行?

我正在开发一个基于 Android 地图的应用程序,但我遇到了一些稳定性问题,我的研究使我相信我需要确保在 UI 线程上执行屏幕更新。

我的应用有来自 GPS 侦听器(我想将其配置为单独的线程)和 UDP 侦听器(已经是单独的线程)的数据,并且它具有通常的 Android 软件生命周期方法集,但我一定是没有经验之类的,因为我不知道在哪里放置更新地图叠加层的代码

(a) 在 UI 线程上, (b) 以重复的方式。

我在轮询或事件驱动过程(可能基于计时器,或传入数据的到达)之间没有偏好,因此任何一种类型的建议都将被接受。

有人有什么想法吗??

谢谢, R.

【问题讨论】:

    标签: android multithreading ui-thread


    【解决方案1】:

    painless threading 上阅读这篇文章,尤其是Activity.runOnUIThread

    【讨论】:

    • 谢谢大家! ArtWorkAD:感谢有关单独线程想法的提示。在发布原始问题后不久,我就开始怀疑这一点。
    • 该死,我又按回车键了!!!我确信有更好的方法(仅通过阅读此页面上的响应),但我使用了 Handler 和 Runnable 并使用 postDelayed() 每 100 毫秒调用一次覆盖更新代码。它并不完美,但似乎确实有效。我会在合理的情况下尽快处理这里的想法。
    【解决方案2】:

    你也可以看看这个Handling Expensive Operations in UI Thread。在您的情况下,您可以执行以下操作:

    公共类 MyActivity 扩展 Activity {

    [ . . . ]
    // Need handler for callbacks to the UI thread
    final Handler mHandler = new Handler();
    
    // Create runnable for posting
    final Runnable mUpdateResults = new Runnable() {
        public void run() {
            updateResultsInUi();
        }
    };
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setup location listener 
        [ . . . ]
        startNonUIThread();
    }
    
    protected void startNonUIThread() {
    
        // Fire off a thread to do some work that we shouldn't do directly in the UI thread
        Thread t = new Thread() {
            public void run() {
               try{
                while(true){
                   sleep(1000); 
                   mHandler.post(mUpdateResults);
                 }
               }catch(InterruptedException e){
                //blah blah
                }
            }
        };
        t.start();
    }
    
    private void updateResultsInUi() {
    
        // Back in the UI thread -- update UI elements based on data from locationlistener
        //get listener location
        //use the location to update the map 
        [ . . . ]
    }
    

    }

    【讨论】:

      【解决方案3】:

      android 定位服务是一个在后台运行的模块,所以你不需要在另一个线程中分离它。

      但是我完全不建议您使用 java 线程类或可运行接口,而是使用异步任务来为您执行所有线程管理。看看 android 开发者博客,Painless Threading

      要在位置更新上更新您的 UI 线程,您可以使用 update handlers。每次有可用的 GPS 数据时,都会向主 ui 线程中的更新处理程序传输一条消息。

      例如

      public void onLocationChanged(Location location) {
          location = this.lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
          try {
              this.mLongitude = location.getLongitude();
              this.mLatitude = location.getLatitude();    
              Message msg = Message.obtain();
              msg.what = UPDATE_LOCATION;
              this.SystemService.myViewUpdateHandler.sendMessage(msg);
          } catch (NullPointerException e) {
              Log.i("Null pointer exception " + mLongitude + "," + mLatitude, null);
          }
      }   
      

      在你的主要活动类中:

      Handler myViewUpdateHandler = new Handler(){
      
              public void handleMessage(Message msg) {
                      switch (msg.what) {
                      case UPDATE_LOCATION:               
                      //do something
                     }
                     super.handleMessage(msg);
              }
          };
      

      【讨论】:

      • 感谢 ArtWork,提醒您注意单独线程的想法。在发布原始问题后不久,我就开始怀疑这一点。我第一次把它放在错误的街区。啊!!
      • 不客气。但请记住,您需要一个更新处理程序来获取 gps 数据。我认为没有办法。我对该主题进行了大量研究,但访问 lng 和 lat 字段时总是遇到空指针异常。所以你需要一些能告诉你gps状态的东西,不管是否真的有gps数据。所以我通过从 gps 实例发送消息来做到这一点。
      • 不确定您所说的“GPS 实例”是什么意思(我是工程师,而不是真正的程序员),但我将 GPS 侦听器设置为带有回调 GpsReadDone 的接口(纬度、经度、 time, dist),由 onLocationChanged() 调用。我的侦听器执行的大多数任务都可以直接执行,但对于屏幕更新,我使用:runOnUiThread (Runnable doScreenUpdates)。使用 postDelayed() DID 工作,但我对实现的非同步性质不满意。我确信实现异步任务会更酷,但现在似乎没有必要(而且令人生畏)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-02-18
      • 2013-01-10
      • 1970-01-01
      • 1970-01-01
      • 2017-07-15
      相关资源
      最近更新 更多