无法在内部类线程中将文本设置为 EditText 或 TextView [重复]

Posted

技术标签:

【中文标题】无法在内部类线程中将文本设置为 EditText 或 TextView [重复]【英文标题】:Can't set text to EditText or TextView in an inner class thread [duplicate] 【发布时间】:2015-05-07 07:37:53 【问题描述】:
    package com.example.multicast;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    import java.net.MulticastSocket;

    import javax.security.auth.PrivateCredentialPermission;

    import android.os.Bundle;
    import android.app.Activity;
    import android.util.Log;
    import android.view.View;
    import android.widget.EditText;
    import android.widget.ProgressBar;
    import android.widget.TextView;
    import android.widget.Toast;

    public class MainActivity extends Activity 
         private EditText txt;
         private ProgressBar bar;
         @Override
             public void onCreate(Bundle savedInstanceState) 
                 super.onCreate(savedInstanceState);
                 setContentView(R.layout.activity_main);
                 txt=(EditText)findViewById(R.id.editText1);
                 bar = (ProgressBar) findViewById(R.id.progressBar1);
             
             public void startProgress(View view) 
                 new Thread(new server()).start();
                 new Thread(new client()).start();
             
             class client implements Runnable 
                 @Override
                 public void run() 
                    try

                        Log.v("ppp","try");
                        MulticastSocket socket = new MulticastSocket(9999);
                        Log.v("ppp","aftrsokt");
                        InetAddress group = InetAddress.getByName("224.0.0.1");
                        Log.v("ppp","b4join");
                        socket.joinGroup(group);
                        Log.v("ppp","join");
                        DatagramPacket packet;
                        byte[] buf = new byte[1024];
                        String received= "";
                        packet = new DatagramPacket(buf, buf.length);
                        Log.v("ppp", "creatpacket");
                        socket.receive(packet);
                        Log.v("ppp", "rcvpackt");
                        received = new String(packet.getData());
                        Log.v("ppp", "rcvd"+received);
                        received =new String(buf,0,packet.getLength());
                        Log.v("ppp","rcvd"+received);
                        txt.setText("ppp");              ///ERROR
                        Log.v("ppp", "aftr txt.settext");
                        bar.setProgress(5);
                        System.out.println("Address: " + received);
                        Toast.makeText(MainActivity.this,"OnClickListener : " + 
                                            " "+received,
                        Toast.LENGTH_LONG).show();
                        socket.leaveGroup(group);
                        socket.close();
                        
                    catch(Exception e)
                        Log.v("ppp","try"+e);
                        
                    
                
             class server implements Runnable 
                byte [] buffer=new byte[1024];
                DatagramPacket packet;
                @Override
                public void run() 
                    try
                        DatagramSocket socket = new DatagramSocket();
                        String ip="haaii";
                        Log.v("ppp","hi");
                        buffer = ip.getBytes();
                        packet = new DatagramPacket(buffer, buffer.length, InetAddress.getByName("224.0.0.1"),9999);
                        socket.send(packet);
                        socket.close();
                        Log.v("ppp","socketclose");
                        
                        catch(Exception e)

                        
                
             
         

这表明错误

android.view.ViewRoot$CalledFromWrongThreadException: 
Only the original thread that created a view hierarchy can touch its views.

如何将文本设置为TextView

xml如下所示

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_
        android:layout_
        android:orientation="vertical" >
        <ProgressBar
            android:id="@+id/progressBar1"
            style="?android:attr/progressBarStyleHorizontal"
            android:layout_
            android:layout_
            android:indeterminate="false"
            android:max="10"
            android:padding="4dip" >
        </ProgressBar>
        <Button
            android:id="@+id/button1"
            android:layout_
            android:layout_
            android:onClick="startProgress"
            android:text="Start" />

        <EditText
            android:id="@+id/editText1"
            android:layout_
            android:layout_
            android:text="Large Text"
            android:textAppearance="?android:attr/textAppearanceLarge" />

    </LinearLayout>

【问题讨论】:

你还搜索栏吗? 【参考方案1】:

只有创建视图层次结构的原始线程才能接触其视图。

只有 UI 线程才能对 UI 进行更改。

您正在尝试从非 UI 线程修改 UI。要在 UI 线程上执行操作,请使用 runOnUiThread() 方法。

                      try
                        Log.v("ppp","try");
                        MulticastSocket socket = new MulticastSocket(9999);
                        Log.v("ppp","aftrsokt");
                        InetAddress group = InetAddress.getByName("224.0.0.1");
                        Log.v("ppp","b4join");
                        socket.joinGroup(group);
                        Log.v("ppp","join");
                        DatagramPacket packet;
                        byte[] buf = new byte[1024];
                        String received= "";
                        packet = new DatagramPacket(buf, buf.length);
                        Log.v("ppp", "creatpacket");
                        socket.receive(packet);
                        Log.v("ppp", "rcvpackt");
                        received = new String(packet.getData());
                        Log.v("ppp", "rcvd"+received);
                        received =new String(buf,0,packet.getLength());
                        Log.v("ppp","rcvd"+received);
                        runOnUiThread(new Runnable() 
                          @Override
                          public void run() 
                            txt.setText("ppp");
                            Log.v("ppp", "aftr txt.settext");
                            bar.setProgress(5);
                            System.out.println("Address: " + received);
                            Toast.makeText(MainActivity.this,"OnClickListener : " + " "+received,Toast.LENGTH_LONG).show();
                          
                        );
                        socket.leaveGroup(group);
                        socket.close();
                      
                      catch(Exception e)
                        Log.v("ppp","try"+e);
                      

【讨论】:

【参考方案2】:

runOnUiThread() 方法内调用txt.setText("ppp") 方法。请注意使用活动上下文调用runOnUiThread方法,因为您正在创建一个内部类,除非您使用活动调用它,否则runOnUiThread方法将不起作用。

【讨论】:

以上是关于无法在内部类线程中将文本设置为 EditText 或 TextView [重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何在android中将EditText提示创建为带有图像的文本

如何在Android Layout中将EditBox中的文本划分为TextView和EditBox

无法在自定义适配器中将 EditText 转换为 TextView

当向量在内部类中时,如何删除指向对象的向量指针

在内部类中使用结构时编译错误

如何在Android中将edittext与微调器合并?