HTC 10的ANR,ExifInterface

时间:2018-02-07 07:21:55

标签: android crash

我在使用HTC 10(htc_pmeuhljapan),Android 7.0的Play商店中收到以下错误消息。

  

输入调度超时(等待发送非键事件,因为触摸的窗口尚未完成处理500.0ms前传递给它的某些输入事件。等待队列长度:25。等待队列头部年龄:15678.7ms。 )

根据this link,我明白哪个是ANR。但我无法重现这一点。

代码如下:

 private void refreshListCameraRoll()
    {
        String[] projection;
        Uri uri;
        Cursor cur;                         
        projection = new String[]{
                MediaStore.Images.Media._ID,
                MediaStore.Images.Media.DATA,
                MediaStore.Images.Media.DATE_ADDED
        };

        uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;               
        cur = getContext().getContentResolver().query(uri,
                projection, // Which columns to return
                null,       // Which rows to return (all rows)
                null,       // Selection arguments (none)
                MediaStore.Images.Media.DATE_ADDED + " DESC"      
        );   
        Log.i("ListingImages", " query count=" + cur.getCount());
        showProgress("Loading...");

        if (cur.moveToFirst()) {
            Long id;
            String path;
            long dateS;

            int idColumn = cur.getColumnIndex(MediaStore.Images.Media._ID);
            int pathColumn = cur.getColumnIndex(MediaStore.Images.Media.DATA);

            int dateSColumn = 
            cur.getColumnIndex(MediaStore.Images.Media.DATE_ADDED);

            do {                   
                id = cur.getLong(idColumn);
                path = cur.getString(pathColumn);
                dateS = cur.getLong(dateSColumn);                   
                long dateMS = dateS / S_IN_A_DAY * MS_IN_A_DAY;
                long differenceDates = 0;
                try {                           
                       Date currentDate = new Date();
                       Date oldDate = new Date(dateMS);                          
                       long difference = Math.abs(currentDate.getTime() - oldDate.getTime());
                       differenceDates = difference / (24 * 60 * 60 * 1000);
                 } catch(Exception e) {
                    e.printStackTrace();
                }
                if(differenceDates <= 31) {
                    ExifInterface intf = null;
                    try {
                        intf = new ExifInterface(path);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    if (intf != null) {
                        String dateString = intf.getAttribute(ExifInterface.TAG_DATETIME);
                        if (dateString != null) {
                            SimpleDateFormat sdf = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss");
                            try {
                                   Date date = sdf.parse(dateString);
                                   dateMS = date.getTime() + MS_IN_A_DAY;
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }
                    Bundle bundle = new Bundle();
                    bundle.putBoolean(MEDIA_BUNDLE_KEY_ISVIDEO, false);
                    bundle.putLong(MEDIA_BUNDLE_KEY_ID, id);
                    bundle.putString(MEDIA_BUNDLE_KEY_PATH, path);
                    bundle.putLong(MEDIA_BUNDLE_KEY_DATE, dateMS);
                    mListMedia.add(bundle);
                }
            } while (cur.moveToNext());
        }
        cur.close();                     
        projection = new String[]{
                MediaStore.Video.Media._ID,
                MediaStore.Video.Media.DATA,
                MediaStore.Video.Media.DATE_ADDED
        };


        uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;        
        cur = getContext().getContentResolver().query(uri,
                projection, // Which columns to return
                null,       // Which rows to return (all rows)
                null,       // Selection arguments (none)
                MediaStore.Video.Media.DATE_ADDED + " DESC"        // Ordering
        );

        Log.i("ListingVideos", " query count=" + cur.getCount());

        if (cur.moveToFirst()) {
            Long id;
            String path;
            long dateS;

            int idColumn = cur.getColumnIndex(MediaStore.Video.Media._ID);
            int pathColumn = cur.getColumnIndex(MediaStore.Video.Media.DATA);
            int dateSColumn = cur.getColumnIndex(MediaStore.Video.Media.DATE_ADDED);

            do {
                // Get the field values
                id = cur.getLong(idColumn);
                path = cur.getString(pathColumn);
                dateS = cur.getInt(dateSColumn);

                //filter media files for ONE month
                long dateMS = dateS / S_IN_A_DAY * MS_IN_A_DAY;
                long differenceDates = 0;
                try {
                    SimpleDateFormat sd = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss");
                    Date currentDate = new Date();
                    Date date = new Date(dateMS);
                    //Comparing dates
                    long difference = Math.abs(currentDate.getTime() - date.getTime());
                    differenceDates = difference / (24 * 60 * 60 * 1000);

                } catch(Exception e) {
                    e.printStackTrace();
                }
                if(differenceDates <= 31) {
                    Bundle bundle = new Bundle();
                    bundle.putBoolean(MEDIA_BUNDLE_KEY_ISVIDEO, true);
                    bundle.putLong(MEDIA_BUNDLE_KEY_ID, id);
                    bundle.putString(MEDIA_BUNDLE_KEY_PATH, path);
                    bundle.putLong(MEDIA_BUNDLE_KEY_DATE, dateS * MS_IN_A_S);
                    mListMedia.add(bundle);

                }
            } while (cur.moveToNext());
        }

        hideProgress();
    }

作为android developer document,ExifInterface在API级别24中添加,因此HTC 10,android 7.0不会出现问题。

以下是播放商店追踪:编辑:

     "main" prio=5 tid=1 Runnable
   | group="main" sCount=0 dsCount=0 obj=0x73eccab0 self=0xebc33400
   | sysTid=12463 nice=0 cgrp=default sched=0/0 handle=0xebcf6534
   | state=R schedstat=( 0 0 0 ) utm=765 stm=278 core=0 HZ=100
   | stack=0xff197000-0xff199000 stackSize=8MB
   | held mutexes= "mutator lock"(shared held)
   at java.io.ByteArrayInputStream.read (ByteArrayInputStream.java)
   at android.media.ExifInterface$ByteOrderAwarenessDataInputStream.readInt (ExifInterface.java:2636)
   at android.media.ExifInterface$ByteOrderAwarenessDataInputStream.readUnsignedInt (ExifInterface.java:2677)
   at android.media.ExifInterface.readImageFileDirectory (ExifInterface.java:2212)
   at android.media.ExifInterface.readImageFileDirectory (ExifInterface.java:2262)
   at android.media.ExifInterface.readExifSegment (ExifInterface.java:2093)
   at android.media.ExifInterface.getJpegAttributes (ExifInterface.java:1892)
   at android.media.ExifInterface.loadAttributes (ExifInterface.java:1474)
   at android.media.ExifInterface.<init> (ExifInterface.java:1111)
   at com.xxxxxxxx.xxxx.AlbumFragment.refreshListCameraRoll (AlbumFragment.java:815)
   at com.xxxxxxxx.xxxx.AlbumFragment.refreshList (AlbumFragment.java:603)
   at com.xxxxxxxx.xxxx.AlbumFragment.setAlbum (AlbumFragment.java:575)
   at com.xxxxxxxx.xxxx.AlbumFragment.access$000 (AlbumFragment.java:103)
   at com.xxxxxxxx.xxxx.AlbumFragment$1.onTabSelected (AlbumFragment.java:264)
   at android.support.design.widget.TabLayout.selectTab (TabLayout.java:1025)
   at android.support.design.widget.TabLayout.selectTab (TabLayout.java:995)
   at android.support.design.widget.TabLayout$Tab.select (TabLayout.java:1272)
   at android.support.design.widget.TabLayout$TabView.performClick (TabLayout.java:1377)
   at android.view.View$PerformClick.run (View.java:22396)
   at android.os.Handler.handleCallback (Handler.java:751)
   at android.os.Handler.dispatchMessage (Handler.java:95)
   at android.os.Looper.loop (Looper.java:173)
   at android.app.ActivityThread.main (ActivityThread.java:6459)
   at java.lang.reflect.Method.invoke! (Native method)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:938)
   at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:828)

确保AlbumFragment.java上的第815行,即

intf = new ExifInterface(path);

这是崩溃的应用程序。对此有任何想法都非常感谢。

1 个答案:

答案 0 :(得分:0)

<强> ANR

&#XA;&#XA;
&#XA;

在您的应用执行可能冗长的任何情况下&#xA;操作,你不应该在UI线程上执行工作,但&#xA;而是创建一个工作线程并在那里完成大部分工作。这&#XA;保持UI线程(驱动用户界面事件循环)&#xA;运行并阻止系统断定您的代码有&#xA;冻结。因为这种线程通常是在类#&xA;等级,您可以将响应性视为一个类问题。 (比较&#xA;这与基本代码性能有关,这是方法级别的考虑。)

&#xA;
&#xA;&#xA;

了解更多信息

&#xA;&#xA;

所以,如果我试图观察你的代码,你在UI线程中做了很多工作,这是抛出ANR的主要原因。因此,您需要将代码放入 AsyncTask

&#xA;&#xA;
 私有类RefreshListCameraRollAsyncTask扩展AsyncTask&lt; String,Void,String&gt; {&#XA;&#XA; @越权#XA; protected String doInBackground(String ... params){&#xA; refreshListCameraRoll();&#XA;返回“已执行”;&#xA; }&#XA;&#XA; @越权#XA; protected void onPostExecute(String result){&#xA; //你的UI在这里工作并隐藏loader&#xA; }&#XA;&#XA; @越权#XA; protected void onPreExecute(){&#xA; //如果你想展示&#xA;在这里展示你的装载机}&#XA;&#XA;&#XA;}&#XA;  
&#XA;