来试试昵称是否必须字母数字下划线
2016-02-22 16:33
采纳率: 66.7%
浏览 2.5k

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)

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

11条回答 默认 最新

  • Wbaokang 2016-02-25 10:04
    已采纳

    弱引用的方式,防止内存泄漏

    点赞 评论
  • blownewbee 2016-02-22 23:16

    先开一个内存Image对象,线程中对它绘图,然后再一次性加载到界面上。

    点赞 评论
  • hyb1996 2016-02-23 00:58

    runOnUiThread(new Runnable(){
    @Override
    public void run() {
    //更新UI,new控件
    }
    }

    点赞 评论
  • hyb1996 2016-02-23 01:05

    直接在线程中addView就好,不然可能出现NullPointerException.

    点赞 评论
  • Wbaokang 2016-02-23 01:24

    挂了是报出了什么错误,粘一下错误日志看下...

    点赞 评论
  • Eileng 2016-02-23 03:02

    根据日志看什么错误, 不然就只有乱猜

    点赞 评论
  • 东风玖哥 2016-02-23 12:42

    这个在onResume里重写一遍就好了吧

    点赞 评论
  • Wbaokang 2016-02-25 10:04

    弄个内存缓存池,把创建的view缓存下来

    点赞 评论
  • 线程里new一个view我还是第一次见,new出来的对象又没使用过,这里局部new的view,主线程也拿不到这个变量。你是否要addview呢,一addview必定报错。线程中绘制界面请了解下surfaceview的双缓冲机制。或者简单实现用线程读取数据,完成之后handler通知view更新。
    我不知道线程里new view行不行,但是我没听说过

    点赞 评论
  • 代码报错看来,显然edittext在创建的时候会自动创建handler,这个handler他需要做什么事,也许是用来通知绘制光标的改变等等。这个handler创建的时候在工作线程了,所以报错了。
    可以去看下new edittext里面的机制。
    我猜,textview在创建的时候不会去new handler所以暂时没报错

    点赞 评论
  • ttfigo 2016-06-12 18:51

    从日志来看new edittextview肯定创建了handler

    点赞 评论

相关推荐 更多相似问题