在 Android 平板电脑地图上绘制叠加层时正确处理主线程连接上的网络

发布于 2024-11-30 18:57:53 字数 2400 浏览 0 评论 0原文

在玩了很多 honeycomb 之后,事实证明,如果你做了任何 HTTP 的事情,它就会引发 NetworkOnMainThread 问题。我通过将对 http 的调用放在一个单独的 AsynTask 中来处理这个问题,这似乎工作得很好...

现在我正在尝试加载正在获取的 WMS 图层(通过 https)并将其放在地图上。这工作正常,但我使用 AsyncTask 的方式并没有削减它,因为每次在覆盖层上调用绘图时(我认为每次移动地图时)它都会执行另一个操作,

new getWmsAsync().execute();

这意味着一段时间后就会出现最大线程。

我不确定正确的解决方法是什么。或者在按照我知道如何失败的方式完成之后如何以正确的方式进行设计。我缺少哪些部分?是否可以在不同的线程上获取 https 请求(我认为每次移动地图时都必须完成)。

原始调用:

WMSOverlay extends Overlay 类中:

@Override
  public void draw(Canvas canvas, MapView mapView,
           boolean shadow) {
   super.draw(canvas, mapView, shadow);
   mCanvas=canvas;
   wmsclient = new WMSLoader(mapView.getContext());
   cornerCoords = MapUtils.getCornerCoordinates(mapView.getProjection(), canvas);

   //new getWmsAsync().execute();
   Paint semitransparent = new Paint();
   semitransparent.setAlpha(0x888);
   mCanvas.drawBitmap( , 0, 0, semitransparent);

  }

但是我的 wsmClient.loadMap 中有 http 调用,因此它会因上述 NetworkOnMainThread 而终止。我的修复是这样的:

@Override
  public void draw(Canvas canvas, MapView mapView,
           boolean shadow) {
   super.draw(canvas, mapView, shadow);
   mCanvas=canvas;
   wmsclient = new WMSLoader(mapView.getContext());
   cornerCoords = MapUtils.getCornerCoordinates(mapView.getProjection(), canvas);

   new getWmsAsync().execute(); //too many threads here...

  }

private class getWmsAsync extends AsyncTask<Void, Void, Bitmap>{
    @Override
     protected void onPostExecute(Bitmap image) {
           Paint semitransparent = new Paint();
           semitransparent.setAlpha(0x888);
           mCanvas.drawBitmap(image, 0, 0, semitransparent);
           this.cancel(true);              
        }
    @Override
    protected Bitmap doInBackground(Void... params) {
        // TODO Auto-generated method stub
        return wmsclient.loadMap(mCanvas.getWidth(), mCanvas.getHeight(), cornerCoords[0], cornerCoords[1], null);
    }         
}

如果我将这种方式与 .execute() 一起使用,我最终会遇到此错误:

08-23 17:01:05.520: ERROR/AndroidRuntime(5436): java.util.concurrent.RejectedExecutionException: Task android.os.AsyncTask$3@41147c88 rejected from java.util.concurrent.ThreadPoolExecutor@40880c00[Running, pool size = 128, active threads = 127, queued tasks = 10, completed tasks = 59]

After playing with honeycomb a lot, it turns out if you do any HTTP stuff it wines about a NetworkOnMainThread issue. I was dealing with this by putting my calls to http in a separate AsynTask and this seemed to work well...

Now I am trying to load a WMS layer im fetching (Via https) and put it on the map. This is working okay but my way of using AsyncTask isn't cutting it as everytime the draw was called on the overlay (which I think is everytime you move the map) it was doing another

new getWmsAsync().execute();

which means after a while there was max threads.

I am not sure what the right fix for this is. Or how to engineer this in the correct way after doing it the way I knew how failed me. What pieces am I missing? Is there away to get the https request on a different thread (it has to be done every time the map is moved I think).

The original calls:

in the WMSOverlay extends Overlay class:

@Override
  public void draw(Canvas canvas, MapView mapView,
           boolean shadow) {
   super.draw(canvas, mapView, shadow);
   mCanvas=canvas;
   wmsclient = new WMSLoader(mapView.getContext());
   cornerCoords = MapUtils.getCornerCoordinates(mapView.getProjection(), canvas);

   //new getWmsAsync().execute();
   Paint semitransparent = new Paint();
   semitransparent.setAlpha(0x888);
   mCanvas.drawBitmap( , 0, 0, semitransparent);

  }

But my wsmClient.loadMap has http calls in it so it dies with the above NetworkOnMainThread. My fix was this:

@Override
  public void draw(Canvas canvas, MapView mapView,
           boolean shadow) {
   super.draw(canvas, mapView, shadow);
   mCanvas=canvas;
   wmsclient = new WMSLoader(mapView.getContext());
   cornerCoords = MapUtils.getCornerCoordinates(mapView.getProjection(), canvas);

   new getWmsAsync().execute(); //too many threads here...

  }

private class getWmsAsync extends AsyncTask<Void, Void, Bitmap>{
    @Override
     protected void onPostExecute(Bitmap image) {
           Paint semitransparent = new Paint();
           semitransparent.setAlpha(0x888);
           mCanvas.drawBitmap(image, 0, 0, semitransparent);
           this.cancel(true);              
        }
    @Override
    protected Bitmap doInBackground(Void... params) {
        // TODO Auto-generated method stub
        return wmsclient.loadMap(mCanvas.getWidth(), mCanvas.getHeight(), cornerCoords[0], cornerCoords[1], null);
    }         
}

if I use that way with the .execute() i end up with this error:

08-23 17:01:05.520: ERROR/AndroidRuntime(5436): java.util.concurrent.RejectedExecutionException: Task android.os.AsyncTask$3@41147c88 rejected from java.util.concurrent.ThreadPoolExecutor@40880c00[Running, pool size = 128, active threads = 127, queued tasks = 10, completed tasks = 59]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

触ぅ动初心 2024-12-07 18:57:53

在玩了很多 honeycomb 之后,事实证明,如果你做了任何 HTTP 的事情,它就会引发 NetworkOnMainThread 问题。

AFAIK,如果您使用 StrictMode,您应该只收到消息。无论如何,比 LogCat 消息更重要的是,如果您在主应用程序线程上执行网络 I/O,您将​​冻结您的 UI。

我不确定正确的解决方法是什么。

通常,您会缓存 HTTP 请求结果,因此无需重新请求它们。

或者,如果您的每个请求都针对不同的数据,请等到用户暂停,然后对最终结果执行单个请求,就像 Google 地图对其自己的地图图块所做的那样。

After playing with honeycomb a lot, it turns out if you do any HTTP stuff it wines about a NetworkOnMainThread issue.

AFAIK, you should only get messages if you are using StrictMode. Regardless, more important than the LogCat messages is that you are freezing your UI if you do network I/O on the main application thread.

I am not sure what the right fix for this is.

Well, typically, you cache your HTTP request results, so you do not need to re-request them.

Or, if each of your requests would be for different data, wait until the user pauses, then do a single request for the end result, the same way Google Maps does it for its own map tiles.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文