【问题标题】:ANR: Input dispatching timed out - Creating a Bitmap from an URLANR:输入调度超时 - 从 URL 创建位图
【发布时间】:2018-10-16 21:26:47
【问题描述】:

在我的 Android 应用程序中,我正在从图像 URL 创建位图。下面是我编写的从图像 URL 创建位图的代码--

 public static Bitmap getBitmapFromURL(String src)
    {
        try
        {
            StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
            StrictMode.setThreadPolicy(policy);

            URL url = new URL(src);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setDoInput(true);
            connection.connect();
            InputStream input = connection.getInputStream();
            Bitmap myBitmap = BitmapFactory.decodeStream(input);
            return myBitmap;
        }
        catch (Exception e)
        {
            e.printStackTrace();
            return null;
        }
    }

我的应用程序在 Play-store 上,并且此代码影响了少数设备,因为它们出现“输入调度超时”ANR。以下是我从 Google Play 控制台的“ANR 和崩溃”部分获得的 ANR 详细信息--

"输入调度超时(等待发送非按键事件,因为触摸的窗口尚未完成对 500.0 毫秒前交付给它的某些输入事件的处理。等待队列长度:60。等待队列头年龄:10502.8ms。)

以下是来自 Google Play 控制台的完整日志--

"main" prio=5 tid=1 Native
  | group="main" sCount=1 dsCount=0 obj=0x75a2c598 self=0xa4e84400
  | sysTid=522 nice=0 cgrp=default sched=0/0 handle=0xa7d13534
  | state=S schedstat=( 0 0 0 ) utm=114 stm=42 core=1 HZ=100
  | stack=0xbe467000-0xbe469000 stackSize=8MB
  | held mutexes=
  #00  pc 0000000000048cb4  /system/lib/libc.so (__ppoll+20)
  #01  pc 000000000001cf3f  /system/lib/libc.so (poll+46)
  #02  pc 0000000000012cb7  /system/lib/libjavacrypto.so (???)
  #03  pc 000000000000f24b  /system/lib/libjavacrypto.so (???)
  #04  pc 000000000000e5cd  /system/framework/arm/boot-conscrypt.oat (Java_com_android_org_conscrypt_NativeCrypto_SSL_1read__JLjava_io_FileDescriptor_2Lcom_android_org_conscrypt_NativeCrypto_00024SSLHandshakeCallbacks_2_3BIII+192)
  at com.android.org.conscrypt.NativeCrypto.SSL_read (Native method)
  at com.android.org.conscrypt.OpenSSLSocketImpl$SSLInputStream.read (OpenSSLSocketImpl.java:761)
- locked <0x06eb358f> (a java.lang.Object)
  at com.android.okhttp.okio.Okio$2.read (Okio.java:142)
  at com.android.okhttp.okio.AsyncTimeout$2.read (AsyncTimeout.java:218)
  at com.android.okhttp.okio.RealBufferedSource.indexOf (RealBufferedSource.java:312)
  at com.android.okhttp.okio.RealBufferedSource.indexOf (RealBufferedSource.java:306)
  at com.android.okhttp.okio.RealBufferedSource.readUtf8LineStrict (RealBufferedSource.java:202)
  at com.android.okhttp.internal.http.HttpConnection.readResponse (HttpConnection.java:210)
  at com.android.okhttp.internal.http.HttpTransport.readResponseHeaders (HttpTransport.java:81)
  at com.android.okhttp.internal.http.HttpEngine.readNetworkResponse (HttpEngine.java:960)
  at com.android.okhttp.internal.http.HttpEngine.readResponse (HttpEngine.java:836)
  at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute (HttpURLConnectionImpl.java:480)
  at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse (HttpURLConnectionImpl.java:422)
  at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream (HttpURLConnectionImpl.java:256)
  at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getInputStream (DelegatingHttpsURLConnection.java:210)
  at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getInputStream (HttpsURLConnectionImpl.java)
  at come.xyz.myapp.util.AppHelper.getBitmapFromURL (AppHelper.java:66)
  at come.xyz.myapp.Adapters.ScratchersAdapter.instantiateItem (ScratchersAdapter.java:706)
  at android.support.v4.view.ViewPager.addNewItem (ViewPager.java:1004)
  at android.support.v4.view.ViewPager.populate (ViewPager.java:1218)
  at android.support.v4.view.ViewPager.populate (ViewPager.java:1086)
  at android.support.v4.view.ViewPager.setAdapter (ViewPager.java:534)
  at come.xyz.myapp.widgets.InfiniteViewPager.setAdapter (InfiniteViewPager.java:40)
  at come.xyz.myapp.Fragments.DailyScratchersFragment.updateAdapter (DailyScratchersFragment.java:965)
  at come.xyz.myapp.Fragments.DailyScratchersFragment.onCaughtContent (DailyScratchersFragment.java:750)
  at come.xyz.coresdk.CoreLibrary.onCaughtContent (CoreLibrary.java:591)
  at come.xyz.coresdk.asynctasks.CatchScratcherSetTask.onPostExecute (CatchScratcherSetTask.java:82)
  at come.xyz.coresdk.asynctasks.CatchScratcherSetTask.onPostExecute (CatchScratcherSetTask.java:22)
  at android.os.AsyncTask.finish (AsyncTask.java:660)
  at android.os.AsyncTask.-wrap1 (AsyncTask.java)
  at android.os.AsyncTask$InternalHandler.handleMessage (AsyncTask.java:677)
  at android.os.Handler.dispatchMessage (Handler.java:102)
  at android.os.Looper.loop (Looper.java:154)
  at android.app.ActivityThread.main (ActivityThread.java:6317)
  at java.lang.reflect.Method.invoke! (Native method)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:872)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:762)

之前在 stackoverflow 上针对同一问题发布了几个问题,但我发现没有一个问题对我有用。如果我可以提供有关此问题的更多信息,请告诉我。谢谢。

【问题讨论】:

    标签: android


    【解决方案1】:

    我相信您正在主线程上下载图像,这会导致 ANR,我相信您需要在后台线程中进行,如 asynctask 或使用这些 3rd 方之一 https://github.com/bumptech/glidehttp://square.github.io/picasso/

    【讨论】:

      【解决方案2】:

      可能是下面一行导致问题

      StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
      StrictMode.setThreadPolicy(policy);
      

      不是通过这种方法做网络功能,而是创建一个AsyncTask,同样的,ANR的产生可能是因为过程太长,所以不要启用srickmode,而是使用AsyncTask

      【讨论】:

      • 我明白你在说什么,我会尝试同样的方法并让你知道状态。谢谢。
      • 这两行用于记录线程中的所有内容,请查看developer.android.com/reference/android/os/…
      • 我曾经在UI线程中使用StrictMode策略进行网络调用,但有时会导致ANR,所以我将其更改为AsyncTask,对于下载图像最好使用Picasso或Glide ,, 省去了很多代码,效率更高
      【解决方案3】:

      实际上将“从 URL 创建位图”代码放入 Asynctask 解决了我的问题。下面是我的代码--

      public class GetBitmapTask extends AsyncTask<String, Void, Bitmap>
      {
          @Override
          protected Bitmap doInBackground(String... urls)
          {
              Bitmap map = null;
              for (String url : urls)
              {
                  map = createBitmapFromURL(url);
              }
              return map;
          }
      
          // Sets the Bitmap returned by doInBackground
          @Override
          protected void onPostExecute(Bitmap resultBitmap)
          {
      
          }
      
      
          public Bitmap createBitmapFromURL(String src)
          {
              try
              {
                  URL url = new URL(src);
                  HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                  connection.setDoInput(true);
                  connection.connect();
                  InputStream input = connection.getInputStream();
                  Bitmap myBitmap = BitmapFactory.decodeStream(input);
                  return myBitmap;
              }
              catch (Exception e)
              {
                  e.printStackTrace();
                  return null;
              }
          }
      }
      

      下面是我如何称呼这个任务--

      Bitmap mBitmap = new GetBitmapTask().execute(strImgUrl).get();
      

      【讨论】:

        猜你喜欢
        • 2016-12-30
        • 2018-04-26
        • 2018-01-29
        • 2022-06-10
        • 2014-09-25
        • 2019-03-19
        • 2018-07-27
        • 2017-04-15
        • 2023-04-05
        相关资源
        最近更新 更多