Android & ldquo; Только исходный поток, создавший иерархию представлений, может касаться его представлений. & Rdquo; ошибка во фрагменте [дубликат]

На этот вопрос уже есть ответ:

У меня в приложении есть простой таймер, который запускается каждые 3 секунды. Он отлично работает, если он не в классе фрагмента. Но здесь во фрагменте я всегда получал ошибку: только исходный поток, создавший иерархию представлений, может касаться его представлений.

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) {
            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) {
            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) {
            e.printStackTrace();
        } catch (ModbusSlaveException e) {
            e.printStackTrace();
        } catch (ModbusException e) {
            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);
29
задан 03.11.2017, 23:27

7 ответов

Эта ошибка возникает при попытке доступа к элементам пользовательского интерфейса из любого потока, который не является потоком пользовательского интерфейса.

Чтобы получить доступ / изменить элементы из не-пользовательского интерфейса, используйте runOnUIThread.

Однако, поскольку вам нужно изменить элемент пользовательского интерфейса из fragment, runOnUIThread следует вызывать для фрагментов, обладающих активностью. Вы можете сделать это через 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.

Для получения дополнительной информации см. Следующую документацию:

  1. Фрагменты Android (в частности, getActivity() ]).
  2. TimerTask .
  3. Вызов Runnable в потоке пользовательского интерфейса.
94
ответ дан 11.10.2019, 17:34
  • 1
    Спасибо!, но как установить время? – David 06.09.2013, 14:39
  • 2
    You' ve потерял меня... Где Вы пытаетесь установить время в своем коде? – matthewrdev 06.09.2013, 14:42
  • 3
    в последней строке "}, 0, 3000); " это означает 3 секунды – David 06.09.2013, 14:43
  • 4
    Право А-ч, поскольку это - выполнимое Вы don' t должен сделать это. I' ll обновляют код для разъяснения. – matthewrdev 06.09.2013, 14:44
  • 5
    Этот TimerTask создается и запускается в корректном классе Фрагмента? В этом случае необходимо будет вызвать runOnUiThread на класс Действия владения, который можно получить путем вызова getActivity (). EG: getActivity () .runOnUIThread (новый Выполнимый ()... – matthewrdev 06.09.2013, 16:04
  • 6
    Я хотел бы использовать Trac, потому что его записанный Python вместо Ruby (я не говорю Ruby, но Python и я хочу сделать свои собственные плагины), но недостающей Многопроектной поддержкой является Остановка для меня. Сделать приблизительно 50 сред Trac, один для каждого проекта?Ни в коем случае. Даже если я думаю, что Redmine имеет несколько недостатков, Redmine является все еще лучшим решением, если у Вас есть много проектов. – fnkr 17.11.2019, 03:03

Вы выполняете операцию пользовательского интерфейса из другого потока. Я предлагаю вам использовать следующее.

runOnUiThread(new Runnable() {  
                @Override
                public void run() {

                    kiir.setText(ki_adat);
                }                   
3
ответ дан 11.10.2019, 17:34
  • 1
    Метод runOnUiThread (новый Выполнимый () {}) не определен для типа новый TimerTask () {} – David 06.09.2013, 15:27
  • 2
    используйте your_activity_name.runOnUiThread.. – Ritesh Gune 06.09.2013, 15:38
  • 3
    Fragment1.this.runOnUiThread (новый Выполнимый () {@Override общественность, пусто выполненная () {//, Этот код будет всегда работать на потоке UI,//поэтому безопасно изменить элементы UI. System.out.println (" FAszom"); kiir.setText (" мой text"); }}); та же ошибка, и это останавливает wirking – David 06.09.2013, 15:42
  • 4
    При использовании его во Фрагменте то используйте getActivity () .runOnUiThread для получения дополнительной информации о runOnUiThread, который я предлагаю, чтобы Вы считали это – Ritesh Gune 06.09.2013, 15:59
  • 5
    Можно добавить: 1. рабочий процесс билета выражения в TRAC просто намного более мощен, чем в RedMine 2. Redmine don' t имеют все же действия, отображенные как non-coder-human-understandable предложения. – Klaim 17.11.2019, 03:03

Попробуйте это:

textView.post(new Runnable() {
    @Override
    public void run() {
    textView.setText("Hello!"); }
});
0
ответ дан 11.10.2019, 17:34
  • 1
    +1 здесь. Установка Redmine таким образом поганая. Руководство никогда не детализирует зависимости ясно. На заключительном шаге Вы понимаете его просто can' t быть интегрированным хорошо с апачем. – Oxdeadbeef 17.11.2019, 03:02

Попробуйте это

new CountDownTimer(365*24*60*60, 3000) {

 public void onTick(long millisUntilFinished) {
     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 = "";
 }

 public void onFinish() {}
}.start();
-1
ответ дан 11.10.2019, 17:34
  • 1
    О, прохладный, загадка. Позволяет видят, сколько времени требуется для нахождения различия между ответом и исходным кодом в вопросе. Ирония прочь:-1 для кода только отвечают без объяснения, что было изменено и почему. – WarrenFaith 06.09.2013, 14:50
  • 2
    @hhh: Ну, на самом деле это - точка SCM. Если Вы не хотите работать над Redmine, Вы, как предполагается, не используете последний ГЛАВНЫЙ пересмотр. Используйте тег или загрузите tarball. – Marc Plano-Lesay 17.11.2019, 03:01

Вам нужно использовать функцию runOnUIThread(). У меня есть пример, который я опубликую, когда найду его.

вам нужно дать вашему таймеру экземпляр MainActivity, в качестве альтернативы посмотрите на этот вопрос, который я задал Проблемы синхронизации изображения Android с тем, что похоже на то, что вы пытались сделать

public static void updateText(Activity act, resID)
{

 loadingText = (TextView) activity.findViewById(R.id.loadingScreenTextView);
          act.runOnUiThread(new Runnable() 
                {
                     public void run() 
                     {
                       loadingText.setText(resID);

                     }

                });
}
8
ответ дан 11.10.2019, 17:34

2 решения:

И поместите вызов myTextView.setText(str) в метод run () объекта Runnable.

2
ответ дан 11.10.2019, 17:34
  • 1
    Я могу помнить время, где разработка была намного быстрее. Также плагины висячей строки являются основной проблемой к Trac. (Конечно, redmine будет также иметь эту проблему), Таким образом, будет все еще разработка, но на намного более низком уровне. Это - моя персональная точка зрения. – math 17.11.2019, 03:02

ПОПРОБУЙТЕ ЭТО: поместите эту часть кода куда-нибудь, но не в действие, на метод CreateCate

public void LoadTable (final String u, final String k) {

    //  runOnUiThread need to be used or error will appear 
    new AsyncTask<Void, Void, Void>() {
        @Override
        protected Void doInBackground(Void... params) {
            try {

                runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                       //method which was problematic and was casing a problem
                       createTable(u, k);
                    }
                });
            } catch (Exception exception) {
                createAndShowDialog(exception, "Error");
            }
            return null;
        }
    }.execute();
}
0
ответ дан 11.10.2019, 17:34
  • 1
    +1 установка RM не легка, заметьте, что МЕРЗАВЕЦ-repo в GitHub является нестабильной разработкой-repo! Потраченным впустую часам с ним и затем реализованный, что программное обеспечение было багги... devs, меньше интересно сохранять ведущее устройство, работающее как gitolite-devs, так загрузите tar - шары. Нет сделайте - файл настолько медленный и болезненный, вероятно, чтобы обновить и поддержать позже, просто предположение. – hhh 17.11.2019, 03:02

Теги

Похожие вопросы