HTC 10的ANR,ExifInterface

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HTC 10的ANR,ExifInterface相关的知识,希望对你有一定的参考价值。

我在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);

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

答案

ANR

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

For more info

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

private class RefreshListCameraRollAsyncTask extends AsyncTask<String, Void, String> {

    @Override
    protected String doInBackground(String... params) {
        refreshListCameraRoll();
        return "Executed";
    }

    @Override
    protected void onPostExecute(String result) {
         // do ur UI work here and hide loader
    }

    @Override
    protected void onPreExecute() {
         // show your loader here if you want to show
    }


}

以上是关于HTC 10的ANR,ExifInterface的主要内容,如果未能解决你的问题,请参考以下文章

ExifInterface返回图像方向0

用ExifInterface读取经纬度的时候遇到的一个问题

使用ExifInterface获取图片信息

从 ExifInterface 获取旋转总是返回 0

xml 回购显示HTC 10(PME)

HTC在新西兰注册商标“Vive Eclipse”或是HTC另外一款VR头显