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线程(驱动用户界面事件循环)保持运行,并阻止系统断定您的代码已冻结。因为这种线程通常是在类级别完成的,所以您可以将响应性视为类问题。 (将其与基本代码性能进行比较,这是方法级别的考虑因素。)
因此,如果我试图观察你的代码,你在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的主要内容,如果未能解决你的问题,请参考以下文章