我在使用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);
这是崩溃的应用程序。对此有任何想法都非常感谢。
答案 0 :(得分:0)
<强> ANR 强>
&#XA;&#XA;&#XA;&#xA;&#xA; &#xA;&#xA;在您的应用执行可能冗长的任何情况下&#xA;操作,你不应该在UI线程上执行工作,但&#xA;而是创建一个工作线程并在那里完成大部分工作。这&#XA;保持UI线程(驱动用户界面事件循环)&#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;