关于Android中一些异常问题的解决办法

// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.2.3'
    }
}


allprojects {
    repositories {
        jcenter()
    }
}
---------------------------------------------------------------------------------------------------------------------


问题总结

1、
在使用AndroidStudio导入项目后,提示图片错误问题,原因是当前AS版本和之前项目版本有差异,根据网络资料,
最新的ADT在AS中必须要使用.9.png图片,解决办法就有两种:
错误:9.png Error:Must have one-pixel frame that is either transparent or white. -xxx/app/src/main/res/drawable-


xhdpi/icon_addpic_focused.png: libpng warning: iCCP: Not recognizing known sRGB profile that has been edited
解决办法一:修改图片名称为.9.png
解决办法二:到build.grade文件中修改
buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.5.0'
    }
}
将classpath 'com.android.tools.build:gradle:1.5.0'的版本改为之前项目的版本,手动修改,比如1.2.3


--------------------------------------------------------------------------------------------------------------------

2、
网络获取图片提示eftexception,参考网络未得到解决
提示nofoundfile原因假如在运行时异常而调试状态下正常,
尝试使用延时处理,和对个任务,线程相关,另外是针对具体项目的逻辑处理考虑因素。
同步轮播显示视图方案:
(1) 同步时刻采用对具体的position设置对应的延时,比如position = 1,延时为1000,position = 2,延时为2000,依次类推。
(2) 采用广播,在listview的可视区域获取相应的view,通过getTag拿取到对应的viewHolder对象,而后进行加载显示。


---------------------------------------------------------------------------------------------------------------------

3、
从一个Activity的某个Fragment跳转到下一个Activity,退栈返回时可能会出现状态被保留,显示了之前的数据后才重新显示正常
正确的数据,原因是和生命周期有关
解决办法为在Fragment的生命周期onStart或者onResume中才做显示控件的数据赋值,具体请看生命周期。该种办法有时候不行,根据具体的逻辑处理看。


-----------------------------------------------------------------------------------------------------------------------------


----------------------------------------

3、

异常错误显示:


07-20 11:30:47.528: E/InputEventReceiver(15683): Exception dispatching input event.
07-20 11:30:47.528: E/MessageQueue-JNI(15683): Exception in MessageQueue callback: handleReceiveCallback
07-20 11:30:47.558: E/MessageQueue-JNI(15683): java.lang.IllegalStateException: The content of the adapter has changed but 


ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but 


only from the UI thread. Make sure your adapter calls notifyDataSetChanged() when its content changes. [in ListView


(2131362029, class android.widget.ListView) with Adapter(class com.apical.aiproforremote.adapter.LoadQueueAdapter)]
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at android.widget.ListView.layoutChildren(ListView.java:1555)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at android.widget.AbsListView.onTouchMove(AbsListView.java:3696)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at android.widget.AbsListView.onTouchEvent(AbsListView.java:3552)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at android.view.View.dispatchTouchEvent(View.java:7731)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2212)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1945)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at android.widget.AbsListView.dispatchTouchEvent(AbsListView.java:930)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2218)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2218)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2218)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2218)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at com.android.internal.policy.impl.PhoneWindow


$DecorView.superDispatchTouchEvent(PhoneWindow.java:2242)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent


(PhoneWindow.java:1536)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at android.app.Activity.dispatchTouchEvent(Activity.java:2501)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent


(PhoneWindow.java:2190)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at android.view.View.dispatchPointerEvent(View.java:7911)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent


(ViewRootImpl.java:4041)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess


(ViewRootImpl.java:3920)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3481)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at android.view.ViewRootImpl$InputStage.onDeliverToNext


(ViewRootImpl.java:3531)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3500)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3607)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3508)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3664)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3481)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at android.view.ViewRootImpl$InputStage.onDeliverToNext


(ViewRootImpl.java:3531)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3500)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3508)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3481)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5629)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5606)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5577)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent


(ViewRootImpl.java:5773)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at android.view.InputEventReceiver.dispatchInputEvent


(InputEventReceiver.java:185)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at android.os.MessageQueue.nativePollOnce(Native Method)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at android.os.MessageQueue.next(MessageQueue.java:138)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at android.os.Looper.loop(Looper.java:123)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at android.app.ActivityThread.main(ActivityThread.java:5128)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at java.lang.reflect.Method.invokeNative(Native Method)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at java.lang.reflect.Method.invoke(Method.java:515)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run


(ZygoteInit.java:893)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:702)
07-20 11:30:47.558: E/MessageQueue-JNI(15683): at dalvik.system.NativeStart.main(Native Method)
07-20 11:30:47.878: E/TestinAgent(15683): ****************************************


该异常出现情况的前提操作:


使用listview做下载队列,首个Item显示有进度条等内容,其余为等待状态,通过广播对数据集做remove操作,并紧接着使用


notifyDataSetChanged刷新适配器。在手势操作,滚动
listview的时候突显这个异常,造成程序崩溃。


通过异常提示内容:线程不是在UI,排除,确定项目中更新在UI中进行。数据集移除直接刷新,应该不会有问题,适配器没有收到数据集改变


的通知,可能数据集指向的内存不是一个,
也排除,适配器中的list用的同一个。


提示中有view的事件传递机制,以及该异常是因为手势操作情况下产生,推测是事件相关,通过监听listview的滚动事件和手势事件,初步解决。


通过监听ListView滚动事件以及手势事件解决办法:


1、定义一个变量用于记录当前是否在滚动中:public boolean isListViewScrolling = false;


2、监听事件:   download_queue_list.setAdapter(loadQueueAdapter);
download_queue_list.setOnScrollListener(new ScrollListenerForListView());
download_queue_list.setOnTouchListener(new GestrueTouchEventListener(this));


3、对应的事件类:private class ScrollListenerForListView implements AbsListView.OnScrollListener{

@Override
public void onScroll(AbsListView paramAbsListView, int firstVisibleItem, int visibleItemCount, int 


totalItemCounts) {
// TODO Auto-generated method stub
total = totalItemCounts;
Log.d("--DownloadQueueActivity--", "--ScrollListenerForListView--" + " totalItemCounts = " + 


totalItemCounts
+ " , loadQueueAdapter.totalItemCount = " + loadQueueAdapter.totalItemCount 
+ " , loadQueueAdapter.removedTotalItemCount = " + 


loadQueueAdapter.removedTotalItemCount);
if ((loadQueueAdapter.removedTotalItemCount != loadQueueAdapter.totalItemCount) ){
loadQueueAdapter.notifyDataSetChanged();
}
}


@Override
public void onScrollStateChanged(AbsListView paramAbsListView, int paramIntStatus) {
// TODO Auto-generated method stub
loadQueueAdapter.isListViewScrolling = true;

if (paramIntStatus == OnScrollListener.SCROLL_STATE_FLING){// ->2
loadQueueAdapter.isListViewScrolling = true;

Log.d("--DownloadQueueActivity--", "--ScrollListenerForListView--2-->" 
+ " , loadQueueAdapter.totalItemCount = " + loadQueueAdapter.totalItemCount 
+ " , loadQueueAdapter.removedTotalItemCount = " + 


loadQueueAdapter.removedTotalItemCount);

if (loadQueueAdapter.removedTotalItemCount != loadQueueAdapter.totalItemCount){
loadQueueAdapter.notifyDataSetChanged();
}

} else if (paramIntStatus == OnScrollListener.SCROLL_STATE_IDLE){// ->0
loadQueueAdapter.isListViewScrolling = false;
loadQueueAdapter.removeDataFromListAgain();

Log.d("--DownloadQueueActivity--", "--ScrollListenerForListView--0-->" 
+ " , loadQueueAdapter.totalItemCount = " + loadQueueAdapter.totalItemCount 
+ " , loadQueueAdapter.removedTotalItemCount = " + 


loadQueueAdapter.removedTotalItemCount);

if ((loadQueueAdapter.removedTotalItemCount != loadQueueAdapter.totalItemCount) ){
loadQueueAdapter.notifyDataSetChanged();
}

int visibleFirstPositionInListView = download_queue_list.getFirstVisiblePosition();
if (visibleFirstPositionInListView == 0){
View view = download_queue_list.getChildAt(0);
if (view == null)
return;
ViewHolder viewHolder = (ViewHolder) view.getTag();

viewHolder.progressbar_load_queue_file_right.setMax(Application.downloadMaxProgress);
viewHolder.progressbar_load_queue_file_right.setProgress


(Application.downloadProgressStep);
viewHolder.text_load_queue_file_info_id.setText(Application.downloadProgressStep + 


"/" + Application.downloadMaxProgress);
}

} else if (paramIntStatus == OnScrollListener.SCROLL_STATE_TOUCH_SCROLL){// ->1
loadQueueAdapter.isListViewScrolling = true;

Log.d("--DownloadQueueActivity--", "--ScrollListenerForListView--1-->" 
+ " , loadQueueAdapter.totalItemCount = " + loadQueueAdapter.totalItemCount 
+ " , loadQueueAdapter.removedTotalItemCount = " + 


loadQueueAdapter.removedTotalItemCount);

if ((loadQueueAdapter.removedTotalItemCount != loadQueueAdapter.totalItemCount) ){
loadQueueAdapter.notifyDataSetChanged();
}

}


}

}

private class GestrueTouchEventListener implements OnGestureListener, OnTouchListener{
GestureDetector mGestureDetector = null;
Context context;

@SuppressWarnings("deprecation")
public GestrueTouchEventListener(Context context){
this.context = context;
mGestureDetector = new GestureDetector(this);
}

@Override
public boolean onDown(MotionEvent arg0) {
// TODO Auto-generated method stub
loadQueueAdapter.isListViewScrolling = true;
return false;
}


@Override
public boolean onFling(MotionEvent arg0, MotionEvent arg1, float arg2,
float arg3) {
// TODO Auto-generated method stub
loadQueueAdapter.isListViewScrolling = true;
return false;
}


@Override
public void onLongPress(MotionEvent arg0) {
// TODO Auto-generated method stub
loadQueueAdapter.isListViewScrolling = true;
}


@Override
public boolean onScroll(MotionEvent arg0, MotionEvent arg1, float arg2,
float arg3) {
// TODO Auto-generated method stub
loadQueueAdapter.isListViewScrolling = true;


return false;
}


@Override
public void onShowPress(MotionEvent arg0) {
// TODO Auto-generated method stub
loadQueueAdapter.isListViewScrolling = true;
}


@Override
public boolean onSingleTapUp(MotionEvent arg0) {
// TODO Auto-generated method stub
loadQueueAdapter.isListViewScrolling = true;
return false;
}


@Override
public boolean onTouch(View arg0, MotionEvent event) {
// TODO Auto-generated method stub
return  mGestureDetector.onTouchEvent(event);
//return false;
}

}


4、在适配器中移除数据项的处理:如果滚动就先做保存,当不滚动的时候再做移除,如上面滚动事件类代码中


loadQueueAdapter.removeDataFromListAgain();。
 
   具体有:public void removeDataFromList(int item){

if (list.size() > 0){
if (isListViewScrolling){
countItemDownloaded++;
laterList.add(item);
return;
} else {
removeDataFromListAgain();
}

if (activity_flag == DOWN_ACTIVITY_FLAG){
list.remove(item);
notifyDataSetChanged();
removedTotalItemCount = list.size();

……

} else if (activity_flag == UP_ACTIVITY_FLAG){
list.remove(item);
notifyDataSetChanged();


……
}
} else {
list = new ArrayList();
notifyDataSetChanged();
}
}




         public void removeDataFromListAgain(){
if (!(countItemDownloaded > 0)){
return ;
}
if (list.size() > 0){
for (int i = 0; i < laterList.size(); i++){
int item = laterList.get(i);
list.remove(item);
notifyDataSetChanged();


                                ……
这种做法的弊端:——可以大致地解决异常冲突,但是存在几个弊端
1、用户操作不规范,有些动作有可能依旧会报出该问题
2、等到不滚动时做移除数据,有可能造成视觉上的错误,突然不见很多Item,或者第一项的进度条分明已经走到最大,
又从头开始但是下载的文件名称还保留着上一个的,可以说,这种办法引起的这个问题,已经算得上是一个BUG,我们
还需要对这种情况进行一些处理,暂时想到的办法为隐藏视图,没有继续尝试,心里感觉这种解决不可行。


解决这个冲突的另一种方案:


使用一个ScrollView嵌套Listview,当然需要自定义ListView使其能够不会和ScrollView产生事件冲突,方法网上有很多。
这样滚动的事件就不是ListView,那么就不会存在正发生着滚动事件和数据项移除没完成notifyDataSetChangedded的情况了。
本方法验证可行。这种方法存在的弊端有可能造成ListView自定义适配器的复用不再有用。
具体的情况还需要根据业务和代码来进行分析和解决。




                











你可能感兴趣的:(异常处理办法记录)