问题描述
- Android线程与ui绘制的问题
-
当然知道只能在主线程更新UI,不过我有个非常费时的UI绘制操作(就是一堆自定义的view退出时保存在文件里,然后进入时读取文件绘制ui恢复界面,实测短板出现在view的绘制过程)然后我一开始觉得只要View不添加就只是对象而已,然后尝试新开一个线程把这些控件new出来,然后在主线程addView,结果在我的平板(5.1.1)上完美运行,在手机(4.2.2)上闪退。
继续测试手机,新开一个线程,一个执行一句new一个edittext就崩溃,不过更加奇怪的是换成textview就正常。完全不明就里。
ps,大家有什么替代方法,也望不吝赐教,感激不尽
按照大家的提醒贴代码(实际的代码太长不便理解,我就写了一个TextView和EditText的,意思一样,而且方便大家理解。)
@Override protected void onAttachedToWindow() { super.onAttachedToWindow(); new Thread(new Runnable() { @Override public void run() { try { new TextView(mActivity); } catch (Exception e) { Log.d("debug", Log.getStackTraceString(e)); return; } Log.d("debug", "成功地new了一个TextView"); try { new EditText(mActivity); } catch (Exception e) { Log.d("debug", Log.getStackTraceString(e)); return; } Log.d("debug", "成功地new了一个EditText"); } }).start(); }
附上Logcat输出:
02-23 03:29:13.144 16364-16440/com.example.multicalc D/debug: 成功地new了一个TextView
02-23 03:29:13.156 16364-16440/com.example.multicalc D/debug: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.(Handler.java:197)
at android.os.Handler.(Handler.java:111)
at android.widget.Editor$UserDictionaryListener.(Editor.java:3836)
at android.widget.Editor.(Editor.java:192)
at android.widget.TextView.createEditorIfNeeded(TextView.java:8475)
at android.widget.TextView.(TextView.java:1114)
at android.widget.EditText.(EditText.java:60)
at android.widget.EditText.(EditText.java:56)
at android.widget.EditText.(EditText.java:52)
at com.example.multicalc.matrix.ui.WorkWindow$1.run(WorkWindow.java:174)
at java.lang.Thread.run(Thread.java:856)
解决方案
弱引用的方式,防止内存泄漏
解决方案二:
先开一个内存Image对象,线程中对它绘图,然后再一次性加载到界面上。
解决方案三:
runOnUiThread(new Runnable(){
@Override
public void run() {
//更新UI,new控件
}
}
解决方案四:
直接在线程中addView就好,不然可能出现NullPointerException.
解决方案五:
挂了是报出了什么错误,粘一下错误日志看下...
解决方案六:
根据日志看什么错误, 不然就只有乱猜
解决方案七:
这个在onResume里重写一遍就好了吧
解决方案八:
弄个内存缓存池,把创建的view缓存下来
解决方案九:
线程里new一个view我还是第一次见,new出来的对象又没使用过,这里局部new的view,主线程也拿不到这个变量。你是否要addview呢,一addview必定报错。线程中绘制界面请了解下surfaceview的双缓冲机制。或者简单实现用线程读取数据,完成之后handler通知view更新。
我不知道线程里new view行不行,但是我没听说过
解决方案十:
代码报错看来,显然edittext在创建的时候会自动创建handler,这个handler他需要做什么事,也许是用来通知绘制光标的改变等等。这个handler创建的时候在工作线程了,所以报错了。
可以去看下new edittext里面的机制。
我猜,textview在创建的时候不会去new handler所以暂时没报错