Android的"只有创建视图层次可以触摸其观点和QUOT原来的线程;片段中的错误 [英] Android "Only the original thread that created a view hierarchy can touch its views." error in Fragment

查看:133
本文介绍了Android的"只有创建视图层次可以触摸其观点和QUOT原来的线程;片段中的错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,我有这个简单的定时器,在我的应用程序,它是运行在每3秒。 它完美的作品,如果它不是在一个片段类。 但这里的片段,我总是得到了错误:只有创建视图层次可以触摸其观点原来的线程。 请帮助我如何改正呢! 谢谢你们!

 定时器=新的Timer();
            timer.schedule(新的TimerTask(){

                @覆盖
                公共无效的run(){
                    字符串的timeStamp =新的SimpleDateFormat(
                            YYYY.MM.DD HH:MM:SS。)格式(日历
                            。.getInstance()的getTime());
                    的System.out.println(时间戳+时间戳);
                    //读写寄存器样品
                    端口=的Integer.parseInt(gConstants.port);
                    字符串refe =0; //十六进制地址
                    REF =的Integer.parseInt(refe,16); //十六进制为int
                    数= 10; //数字地址读
                    SlaveAddr = 1;
                    而aStr = gConstants.ip; // Modbus设备

                    InetAddress类地址;
                    尝试 {
                        地址= InetAddress.getByName(而aStr);
                        CON =新TCPMasterConnection(地址); //的
                        // 连接
                    }赶上(UnknownHostException异常E2){
                        // TODO自动生成的catch块
                        e2.printStackTrace();
                    }

                    // 1. prepare请求
                    / ************** /
                    RREQ =新ReadMultipleRegistersRequest(REF,计数);
                    RRES =新ReadMultipleRegistersResponse();

                    Rreq.setUnitID(SlaveAddr); //设置从地址
                    Rres.setUnitID(SlaveAddr); //设置从地址

                    // 2.打开连接
                    con.setPort(端口);
                    尝试 {
                        con.connect();
                        的System.out.println(Kapcsolódva!);
                    }赶上(例外E1){
                        // TODO自动生成的catch块
                        e1.printStackTrace();
                    }
                    con.setTimeout(2500);
                    // 3.开始交易
                    反=新ModbusTCPTransaction(CON);
                    trans.setRetries(5);
                    trans.setReconnecting(真正的);
                    trans.setRequest(RREQ);

                    尝试 {
                        trans.execute();
                    }赶上(ModbusIOException E){
                        // TODO自动生成的catch块
                        e.printStackTrace();
                    }赶上(ModbusSlaveException E){
                        // TODO自动生成的catch块
                        e.printStackTrace();
                    }赶上(ModbusException E){
                        // TODO自动生成的catch块
                        e.printStackTrace();
                    }
                    / *打印响应* /
                    RRES =(ReadMultipleRegistersResponse)反
                            .getResponse();

                    的System.out.println(已连接到=+而aStr
                            + con.isConnected()+/开始注册
                            + Integer.toHexString(REF));

                    数= 10;
                    对于(INT K = 0; K<计数; k ++){
                        的System.out.println(的值改为
                                + Rres.getRegisterValue(K)+
                                + Rres.getUnitID());
                        ki_adat = ki_adat + Rres.getRegisterValue(K)+\ N的;


                        //AdatbázisbaIRAS
                        ContentValues​​ modbusData =新ContentValues​​();
                        modbusData.put(价值,Rres.getRegisterValue(K)); //塔布拉
                                                                            // +
                                                                            //érték
                        modbusData.put(时间戳,时间戳);
                        尝试 {
                            gConstants.db.beginTransaction();
                            gConstants.db
                                    .insert(MODBUS,空,modbusData);
                            gConstants.db.setTransactionSuccessful();
                        } 最后 {
                            gConstants.db.endTransaction();
                        }

                    }
                    kiir.setText(ki_adat);
                    ki_adat =;
                } //运行VEGE

            },0,3000);
 

解决方案

试图从任何线程不是UI线程访问UI元素时,会出现此错误。

要访问/修改了一个从非UI线程元素,使用 runOnUIThread

不过,因为你需要从片段中改变UI元素 runOnUIThread 被调用到的碎片拥有活动。您可以通过 getActivity()做到这一点。runOnUIThread()

例如:

  timer.schedule(新的TimerTask(){
    @覆盖
    公共无效的run(){
        //此处是您的逻辑?

        //当你需要修改UI元素,这样做的UI线程。
        //'getActivity()'是必需的,因为这是从一个片段被然。
        getActivity()。runOnUiThread(新的Runnable(){
            @覆盖
            公共无效的run(){
                //这个code将始终运行在UI线程上,因此可以安全地修改用户界面元素。
                myTextBox.setText(我的文字);
            }
        });
    }
},0,3000); //你的计时器code结束。
 

有关更多信息,请参见以下文档:

  1. Android的碎片(具体而言,<一个href="http://developer.android.com/reference/android/app/Fragment.html#getActivity%28%29"><$c$c>getActivity()).
  2. 的TimerTask
  3. <一个href="http://developer.android.com/reference/android/app/Activity.html#runOnUiThread%28java.lang.Runnable%29">Invoking一个Runnable UI线程。

hi i've got this simple timer in my app which is runs in every 3 seconds. it works perfectly if it's not in a fragment class. But here in fragment i always got the error: Only the original thread that created a view hierarchy can touch its views. Please help me how to correct it! Thank you guys!

timer = new Timer();
            timer.schedule(new TimerTask() {

                @Override
                public void run() {
                    String timeStamp = new SimpleDateFormat(
                            "yyyy.MM.dd HH:mm:ss").format(Calendar
                            .getInstance().getTime());
                    System.out.println("TimeStamp: " + timeStamp);
                    // Read And Write Register Sample
                    port = Integer.parseInt(gConstants.port);
                    String refe = "0";// HEX Address
                    ref = Integer.parseInt(refe, 16);// Hex to int
                    count = 10; // the number Address to read
                    SlaveAddr = 1;
                    astr = gConstants.ip; // Modbus Device

                    InetAddress addr;
                    try {
                        addr = InetAddress.getByName(astr);
                        con = new TCPMasterConnection(addr); // the
                        // connection
                    } catch (UnknownHostException e2) {
                        // TODO Auto-generated catch block
                        e2.printStackTrace();
                    }

                    // 1.Prepare the request
                    /************************************/
                    Rreq = new ReadMultipleRegistersRequest(ref, count);
                    Rres = new ReadMultipleRegistersResponse();

                    Rreq.setUnitID(SlaveAddr); // set Slave Address
                    Rres.setUnitID(SlaveAddr); // set Slave Address

                    // 2. Open the connection
                    con.setPort(port);
                    try {
                        con.connect();
                        System.out.println("Kapcsolódva!");
                    } catch (Exception e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }
                    con.setTimeout(2500);
                    // 3. Start Transaction
                    trans = new ModbusTCPTransaction(con);
                    trans.setRetries(5);
                    trans.setReconnecting(true);
                    trans.setRequest(Rreq);

                    try {
                        trans.execute();
                    } catch (ModbusIOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } catch (ModbusSlaveException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } catch (ModbusException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    /* Print Response */
                    Rres = (ReadMultipleRegistersResponse) trans
                            .getResponse();

                    System.out.println("Connected to=  " + astr
                            + con.isConnected() + " / Start Register "
                            + Integer.toHexString(ref));

                    count = 10;
                    for (int k = 0; k < count; k++) {
                        System.out.println("The value READ: "
                                + Rres.getRegisterValue(k) + " "
                                + Rres.getUnitID());
                        ki_adat = ki_adat + Rres.getRegisterValue(k) + "\n";


                        // Adatbázisba írás
                        ContentValues modbusData = new ContentValues();
                        modbusData.put("Value", Rres.getRegisterValue(k)); // tábla
                                                                            // +
                                                                            // érték
                        modbusData.put("timeStamp", timeStamp);
                        try {
                            gConstants.db.beginTransaction();
                            gConstants.db
                                    .insert("Modbus", null, modbusData);
                            gConstants.db.setTransactionSuccessful();
                        } finally {
                            gConstants.db.endTransaction();
                        }

                    }
                    kiir.setText(ki_adat);
                    ki_adat = "";
                }//run vége

            }, 0, 3000);

解决方案

This error occurs when trying to access UI elements from any thread that is not the UI thread.

To access/modify elements from a non-UI-thread, use runOnUIThread.

However as you need to change a UI element from within a fragment, runOnUIThread should be invoked onto the fragments owning activity. You can do this through getActivity().runOnUIThread().

EG:

timer.schedule(new TimerTask() {
    @Override
    public void run() {
        // Your logic here...

        // When you need to modify a UI element, do so on the UI thread. 
        // 'getActivity()' is required as this is being ran from a Fragment.
        getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                // This code will always run on the UI thread, therefore is safe to modify UI elements.
                myTextBox.setText("my text");
            }
        });
    }
}, 0, 3000); // End of your timer code.

For further information see the following documentation:

  1. Android Fragments (specifically, getActivity()).
  2. TimerTask.
  3. Invoking a Runnable on the UI thread.

这篇关于Android的&QUOT;只有创建视图层次可以触摸其观点和QUOT原来的线程;片段中的错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆