android 疑难杂症

解决AndroidSQLite-close()was never explicitly called on database异常

这个异常的抛出并没有让程序崩溃。

    这些异常信息来源于SQLiteDatabase类的finalize方法。从异常的信息"close() was never explicitly called on database ,Application did not close the cursor or database object that was opened here
"可以知道这是由于程序中使用到的游标或SQLiteDatabase对象没有close所导致。也就是说在程序中创建的Cursor对象或者SQLiteDatabase对象,在使用完后没有关闭,而当它们都变成“垃圾"被GC时,就会打出以上的信息。

android.database.sqlite.DatabaseObjectNotClosedException: 

所以要想不发生这样的错误,在编码时一定要记住,当你不在使用Cursor或SQLiteDatabase对象时,将它们close()。

 

 

 慎用AsyncTask

Current thread has not called Looper.prepare(). Forcing synchronous mode

不气不馁,根据现象3,又脑洞大开,想是否是AsyncHttpClient同步网络请求时,由于非Looper线程,导致回调执行是在UI线程中,造成了UI线程的阻塞?想到就做,我直接将AsyncTask改成IntentService实现,试了下,不卡顿了,oh yeah!但同时引入新的问题,通讯录的操作没执行,想了下,it's nothing, Service组件是要声明在AndroidManifest.xml中的,试了下,两个问题都完美解决!

 如果止步于此,那就太low了,看了下AsyncHttpResponseHandler的代码,发现如果在非Looper线程中执行,那回调的代码就在执行网络请求(HttpClient.execute())的线程中执行。而且,我用的是同步请求,网络请求直接在发起网络请求(AsyncHttpClient.post())的线程中执行。也就是网络请求、网络请求的回调处理都是在AsyncTask的doInBackground()的线程中执行的。也就不存在回调在UI线程执行,造成UI线程阻塞的问题。

,google下"慎用AsyncTask",随便打开几篇文章,第一个坑:AsyncTask在Android各个版本中可以算是频繁修改了,比较各版本代码发现,修改过多次,而且这种修改会导致很大的差别。最坑的修改是在Android 4.0开始的,AsyncTask的中execute方法的实现在4.0以前是采用Thread pool executor,各个版本对线程池中的可并行线程数限制不同,但毕竟多个Task是多线程并行。而在4.0开始,改为用serial executor,就是说同一时间只能有一个线程运行,其他线程必须等待该线程完成之后才能开始执行,因此就变成了串行的worker thread。” “3、串行和并行多版本不一致 AsyncTask在1.6之前为串行,在1.6-2.3为并行,在3.0之后又改为串行,在3.0之后虽然可以通过代码来改变默认的串行为并行,但是又是一个繁琐的操作”。

Can't create handler inside thread that has not called Looper.prepare()解决办法

Message msg = new Message();       

msg.what = ID_USER;  

mHandler.sendMessage(msg); // 向Handler发送消息,更新UI  

 

Message msg = new Message();       

msg.what = ID_USER;  

 mHandler.sendMessage(msg); // 向Handler发送消息,更新UI   

android api (82) —— InputConnection [输入法]

public abstract boolean finishComposingText ()

  强制结束文本编辑器,无论联想输入(composing text)是否激活。文本保持不变,移除任何与此文本的编辑样式或其他状态。光标保持不变。

android在学习——activity关闭和dialog.dismiss冲突的解决(Activity has leaked window com.android.internal.policy.impl.PhoneWindow)

其意思大概就是:窗体已经关闭了但是dialog仍然在显示,Activity has leaked window(activity渗透出窗体),大概就是这个意思。那么就要在activity finish()之前将dialog dismiss()掉。

protected void onDestroy() {
        // TODO Auto-generated method stub
        try{
            myDialog.dismiss();
        }catch (Exception e) {
            System.out.println("myDialog取消,失败!");
            // TODO: handle exception
        }
        super.onDestroy();

关于android.view.WindowLeaked(窗体泄露)的解决方案

android.view.WindowLeaked一般会发生在Activity 与Dialog的显示。
       Activity 中create 一个Dialog,若你先关闭Dialog再关闭Activity就是正常的,若你先关闭Activity再关闭Dialog就会报错这个android.view.WindowLeaked错误了。
       分析这个原因是:Dialog是基于Activity而创建的:new ProgressDialog(this);this 就是Activity。 Activtity先finish,那Dialog就没得依附了,所以就会报android.view.WindowLeaked。

Android 开发 对话框Dialog dismiss和hide方法的区别

dismiss和hide方法都可以隐藏对话框,在需要的时候也可以用show方法调用显示。但是,这两者是有区别的。

dismiss方法会释放对话框所占的资源,而hide方法不会。activity退出前必须调用dismiss方法关闭对话框。
如果对话框上有progressbar,你会发现,调用dismiss方法后,再调用show方法,出来的对话框,上面的progressbar不再会转动,而调用hide方法的则没有问题。
所以,最正确的调用方法是,在activity的onDestory方法里调用dismiss方法,其他地方都用hide方法隐藏对话框。

posted @ 2017-10-24 15:42  米粥米  阅读(165)  评论(0编辑  收藏  举报