无法在内部类线程中将文本设置为 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