我有以下问题。在主线程上,我有一个EditText
字段,还有一个AsyncTask
,它无限地侦听传入消息的套接字。在循环(位于doInBackground()
中)中,我试图调用onProgressUpdate()
并向其传递一个字符串,我希望当oPU()接收到该字符串时,将其显示在位于主线程的EditText
上。
public class ClientSide extends AsyncTask<String, String, String>{
public EditText field = (EditText) findViewById(R.id.bar1);
...}
第一个问题是findViewById(R.id.bar1)
上的,它说无法解决符号。可能是什么原因导致的,我该如何修复。第二个问题是循环。问题是,我不想通过主线程周期性地创建新的AsyncTask
对象,因为在我的情况下,这意味着每次对象为.execute()-ed时都要创建一个套接字并绑定到它。我知道AsyncTasks
是指短流程,而不是长流程,所以我知道我目前的解决方案(带循环)是一个分解的胡萝卜(又称坏胡萝卜)。再次:1.如何使findViewById()
真正匹配EditText
UI元素?2.当应用程序需要在后台执行消息侦听器时,如何重新组织我的代码,以避免每次都创建套接字?
您可以看到Async。。doInBackground:
protected String doInBackground(String... params){
final String SERVER_HOSTNAME = "hereGoesMyIP";
final int SERVER_PORT = 2002;
BufferedReader mSocketReader;
PrintWriter mSocketWriter;
final String TAG = ClientSide.class.getSimpleName();
String outputln = "Me. Android";
try {
//Initialization of the socket, socket reader and writer.
Socket socket = new Socket(SERVER_HOSTNAME, SERVER_PORT);
mSocketReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
mSocketWriter = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
System.out.println("Connected to server " + SERVER_HOSTNAME + ":" + SERVER_PORT);
//An infinite loop which checks for incoming messages.
while(true){
String inMsg="";
String aMessage = "";
//Reads from the socket
if((inMsg=mSocketReader.readLine())!=null && socket.isConnected()){
publishProgress(inMsg);
}
Thread.sleep(500);//still requres try - catch?
}
} catch (IOException ioe) {
System.err.println("Cannot connect to " + SERVER_HOSTNAME + ":" + SERVER_PORT);
ioe.printStackTrace();
}
return null;
}
1)findViewByid()
是可在Activity类中使用的方法。它在AsyncTask类中不可用。所以把你的视图传递给AsyncTask,就像这个
private Context mContext;
private View yourView;
public Clientside(Context context, View rootView){
this.mContext=context;
this.yourView=rootView;
}
然后你可以像这个一样访问它
EditText editText = yourView.findViewById(R.id.edit_text);
请记住,您无法从后台线程更新视图,因此请使用progressupdate()
或postExecute()
方法更新在主线程上运行的EditText。
@Override
protected void onPostExecute(String result) {
}
View rootView = findViewById(android.R.id.content).getRootView();//This will return you the rootView
ClientSide cs = new ClientSide(getApplicationContext(),rootView);//do this in your mainactivity
getApplicationContext()将返回您所在的上下文。
谢谢。我希望这会有所帮助。
我认为要停止此问题,您必须在onProgressUpdate中刷新EditText
例如:
protected void onProgressUpdate(String newText) {
field.setText(newText);
field.invalidate();
}
并在主线程的外部声明字段变量。。不在客户端类中。。
此onProgressUpdate(..)在您的ClientSide中。。