2013-09-06 22 views
26

Tôi đã có bộ hẹn giờ đơn giản này trong ứng dụng của tôi chạy trong mỗi 3 giây. Nó hoạt động hoàn hảo nếu nó không nằm trong một lớp phân đoạn. Nhưng ở đây trong mảnh tôi luôn luôn có lỗi: Chỉ có các chủ đề ban đầu mà tạo ra một hệ thống phân cấp xem có thể chạm vào quan điểm của nó.Android "Chỉ chuỗi ban đầu đã tạo phân cấp chế độ xem mới có thể chạm vào chế độ xem của nó". lỗi trong Fragment

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); 

Trả lời

83

Lỗi này xảy ra khi cố gắng truy cập các phần tử giao diện người dùng từ bất kỳ chuỗi nào không phải là chuỗi giao diện người dùng.

Để truy cập/sửa đổi các phần tử từ chuỗi không phải là giao diện người dùng, hãy sử dụng runOnUIThread.

Tuy nhiên, khi bạn cần thay đổi phần tử giao diện người dùng từ trong một số fragment, runOnUIThread cần được gọi lên hoạt động sở hữu phân đoạn. Bạn có thể làm điều này thông qua 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. 

Để biết thêm thông tin xem tài liệu sau đây:

  1. Android Fragments (đặc biệt, getActivity()).
  2. TimerTask.
  3. Invoking a Runnable on the UI thread.
+0

thx! nhưng làm thế nào để đặt thời gian? – David

+1

Bạn đã mất tôi ... Bạn đang cố gắng đặt thời gian trong mã của mình ở đâu? – matthewrdev

+0

ở dòng cuối cùng "}, 0, 3000);" nó có nghĩa là 3sec – David

8

bạn cần sử dụng hàm runOnUIThread() Tôi có ví dụ ở nơi tôi sẽ đăng khi tìm thấy.

bạn cần phải cung cấp cho timer của bạn một thể hiện của MainActivity cách khác xem câu hỏi này, tôi hỏi Android image timing issues với những gì có vẻ như một điều tương tự với những gì bạn đang cố gắng để làm

public static void updateText(Activity act, resID) 
{ 

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

        } 

       }); 
} 
+0

cảm ơn bạn! Tôi đang hẹn hò :) – David

3

Bạn đang thực hiện thao tác giao diện người dùng từ thread khác . Tôi đề nghị bạn sử dụng sau đây.

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

        kiir.setText(ki_adat); 
       }     
+0

Phương thức runOnUiThread (Runnable mới() {}) không được định nghĩa cho loại TimerTask mới() {} – David

+0

sử dụng your_activity_name.runOnUiThread .. –

+0

Fragment1.this.runOnUiThread (Runnable mới() { \t \t \t \t \t \t \t @ Override \t \t \t \t \t \t \t public void run() { \t \t \t \t \t \t \t \t // Đoạn mã này sẽ luôn luôn chạy trên thread UI, \t \t \t \t \t \t \t \t // do đó là an toàn để sửa đổi các yếu tố giao diện người dùng. \t \t \t \t \t \t \t \t System.out.println ("FAszom"); \t \t \t \t \t \t \t \t kiir.setText ("văn bản của tôi"); \t \t \t \t \t \t \t} \t \t \t \t \t \t}); lỗi tương tự, và nó dừng wirking – David

-1

Hãy thử

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(); 
+3

Oh cool, một câu đố. Cho phép xem mất bao nhiêu thời gian để tìm ra sự khác biệt giữa câu trả lời của bạn và mã ban đầu trong câu hỏi. Irony off: -1 cho mã chỉ trả lời mà không giải thích những gì đã thay đổi và tại sao. – WarrenFaith

0

TRY NÀY: đặt phần mã này ở đâu đó nhưng không phải trong hoạt động onCreate phương pháp

public void LoadTable (String thức u, thức Chuỗi 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

Hãy thử điều này:

textView.post(new Runnable() { 
    @Override 
    public void run() { 
    textView.setText("Hello!"); } 
});