gpt4 book ai didi

java - 在扩展 AsyncTask 的类中使用 DoInBackground 方法来更改不是 MainActivity 的 Activity 中 TextView 的文本

转载 作者:太空宇宙 更新时间:2023-11-04 10:31:29 25 4
gpt4 key购买 nike

我是一名大学生,正在编写一个 Android 应用程序,该应用程序将显示 Android 设备通过 TCP 从服务器接收的消息。

ListenForMessage 类(扩展 AsyncTask)打开 TCP 连接并在 DoInBackground 方法中从服务器接收消息。我可以在日志中打印出来自服务器的消息,但如果我尝试编辑 TextView 的文本,我的应用程序就会崩溃。看来我无法通过 DoInBackground 方法编辑 TextView 的文本,尤其是不能,因为该类不会扩展创建 TextView 的 Activity 。

我有两个 Activity ,并且我正在第二个 Activity “StreamPageMain”的 onCreate 中执行类“ListenForMessage”(在此之前,我从 MainActivity 中执行它,但这也不起作用)。我试图让该方法知道 TextView 属于哪个 Activity ,正如您在我的代码中看到的那样,我在“ListenForMessage”类中创建了另一个方法来设置文本,这样就不会尝试更改文本的 DoInBackground 方法,但这些都不起作用。

摘要:我已经在代码中标记了出错的地方。我需要做的是以某种方式获取名为“message”的字符串,并将该字符串放入 ID 为“textView1”的 TextView 中,该字符串是“StreamPageMain” Activity 的一部分,而不是 MainActivity。

当按下按钮时,我在 MainActivity 中开始使用此方法:

 public void stream(View V) {

EditText IPText = (EditText) findViewById(R.id.editTextBox2); //Extracting the IP from an EditTextView
EditText portText = (EditText) findViewById(R.id.editTextBox3); //Extracting the port from an EditTextView

String IP = IPText.getEditableText().toString(); //correcting the format to String
Integer port = Integer.parseInt(portText.getEditableText().toString()); //correcting the format to Integer

Intent i = new Intent(MainActivity.this, StreamPageMain.class);
i.putExtra("IP", IP);
i.putExtra("port", port);
startActivity(i);
}

第二个 Activity “StreamPageMain”已启动。这样可行。

import android.widget.VideoView;   

public class StreamPageMain extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.stream_page);

Log.d("StreamingApp", "OnCreate is running.");

//In this middle part I am implementing a videostream into the second
activity, but that does not affect anything

String IP = getIntent().getStringExtra("IP");
Integer port = getIntent().getExtras().getInt("port");
ListenForMessage listenForMessage = new ListenForMessage(StreamPageMain.this, IP, port);
listenForMessage.execute();
}
}

您可以看到,我如何将 Activity StreamPageMain 传递到此处的 ListenForMessage 类。如果我注释掉标记行,类本身、连接和一切都会正常工作:

package comn.example.ezio.streamingapp;

import android.app.Activity;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;

public class ListenForMessage extends AsyncTask<Void, Void, Void> {

public Activity executingActivity;
public String IP;
public Integer port;

public ListenForMessage(Activity activity, String IPString, Integer portNumber) {
this.executingActivity = activity;
IP = IPString;
port = portNumber;
}

@Override
protected Void doInBackground(Void... voids) {

try (Socket socket = new Socket(IP, port)) {

Boolean connectionCancelled = false;

while (connectionCancelled == false) {

InputStreamReader isr = new InputStreamReader(socket.getInputStream());
BufferedReader br = new BufferedReader(isr);
String message = br.readLine();
Log.d("StreamingApp", "Server says: " + message);

setTextOfTextView(message); //!!!! This is it. At this line it
//crashes, no matter how I put it.
//Doing it directly here or in an
//extra method like now.
}

} catch (
UnknownHostException e)

{
e.printStackTrace();
} catch (
IOException e)

{
e.printStackTrace();
}
return null;
}

public void setTextOfTextView(String textOfTextView) {
TextView textView1 = executingActivity.findViewById(R.id.textView1);
textView1.setText("Server says: " + textOfTextView);
}
}

我毕竟对 Java 很陌生,我的知识并没有超出我在这里发布的内容。请原谅格式错误和非最佳实践,我很乐意学习和改进!

最佳答案

正如您所见,您无法更改 doInBackground 中的 UI因为那里的代码是在另一个线程中执行的,你只能在UI线程中对UI进行更改。 (不过,您可以从另一个线程将更改发布到 UI 线程)。

更新 AsyncTasks 中的 UI您可以使用onProgressUpdate更新 UI,因为这里的代码在 UI 线程上运行。您可以在 AsyncTask 中重写此方法:

protected void onProgressUpdate(String... progress) {
setTextOfTextView(progress[0]);
}

doInBackground 发送更新在 onProgressUpdate 中调用方法 publishProgress()

@Override
protected Void doInBackground(Void... voids) {

try (Socket socket = new Socket(IP, port)) {

Boolean connectionCancelled = false;

while (connectionCancelled == false) {

InputStreamReader isr = new InputStreamReader(socket.getInputStream());
BufferedReader br = new BufferedReader(isr);
String message = br.readLine();
Log.d("StreamingApp", "Server says: " + message);

publishProgress(message); //!!!! This is it. At this line it
//crashes, no matter how I put it.
//Doing it directly here or in an
//extra method like now.
}

} catch (
UnknownHostException e)

{
e.printStackTrace();
} catch (
IOException e)

{
e.printStackTrace();
}
return null;
}

编辑:

此外,为了发布任何结果,您应该将 AsyncTask 签名更改为 AsyncTask<Void, String, Void>

关于java - 在扩展 AsyncTask 的类中使用 DoInBackground 方法来更改不是 MainActivity 的 Activity 中 TextView 的文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49955477/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com