java - 从另一个类设置 TextView 文本
问题描述
我想从异步线程更新 TextView,所以我尝试使用回调方法来完成。问题是调用了回调,但 TextView 中没有文本更改。
这是回调接口:
interface MyCallBack {
public void UpdateMyText(String mystr);
}
这是活动(不完整)代码:
package it.italprogetti.datalogic;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.ViewGroup;
import android.widget.TextView;
import java.net.*;
import java.sql.*;
import com.datalogic.*;
public class Scan extends AppCompatActivity implements MyCallBack {
private final String LOGTAG = getClass().getName();
String mes = "";
BarcodeManager decoder = null;
ReadListener listener = null;
TextView message = null;
TextView message2 = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scan);
}
@Override
protected void onResume() {
super.onResume();
message = (TextView) findViewById(R.id.scanMessage);
message2 = (TextView) findViewById(R.id.scanMessage2);
final MyCallBack scan = this;
Log.i(LOGTAG, "onResume");
// If the decoder instance is null, create it.
if (decoder == null) { // Remember an onPause call will set it to null.
decoder = new BarcodeManager();
}
// From here on, we want to be notified with exceptions in case of errors.
ErrorManager.enableExceptions(true);
try {
// Create an anonymous class.
listener = new ReadListener() {
// Implement the callback method.
@Override
public void onRead(DecodeResult decodeResult) {
// Change the displayed text to the current received result.
new RetrieveFeedTask(scan).execute(decodeResult);
}
};
// Remember to add it, as a listener.
decoder.addReadListener(listener);
} catch (DecodeException e) {
Log.e(LOGTAG, "Error while trying to bind a listener to BarcodeManager", e);
}
}
@Override
protected void onPause() {
super.onPause();
Log.i(LOGTAG, "onPause");
// If we have an instance of BarcodeManager.
if (decoder != null) {
try {
// Unregister our listener from it and free resources.
decoder.removeReadListener(listener);
// Let the garbage collector take care of our reference.
decoder = null;
} catch (Exception e) {
Log.e(LOGTAG, "Error while trying to remove a listener from BarcodeManager", e);
}
}
}
@Override
public void UpdateMyText(String mystr) {
Log.i("CALLBACK", "CALLBACK INVOKED!" + mystr);
message2.setText(mystr);
ViewGroup vg = findViewById(R.id.mainLayout);
vg.invalidate();
}
这是异步任务类:
class RetrieveFeedTask extends AsyncTask<DecodeResult, String, String> {
private static final String url = "jdbc:mysql://192.9.200.23/automazione";
private static final String user = "root";
private static final String pass = "root";
private Exception exception;
MyCallBack mCallBack = null;
public RetrieveFeedTask(MyCallBack callback) {
Log.i("CREATO ASYNCH", "ASYNCH");
this.mCallBack = callback;
}
protected String doInBackground(DecodeResult... codes) {
try {
String codice = codes[0].getText();
codice = codice.substring(0, 8);
Log.i("SCAN", "SCANNED" + codice);
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection(url, user, pass);
String result = "Database connection success\n";
Statement st = con.createStatement();
Log.i("SCAN", "select * from utenti where code='" + codice + "'");
ResultSet rs = st.executeQuery("select * from utenti where code='" + codice + "'");
ResultSetMetaData rsmd = rs.getMetaData();
while (rs.next()) {
Log.i("OPERATOR IDENTIFIED", rs.getString(4));
this.mCallBack.UpdateMyText("OPERATOR IDENTIFIED " + rs.getString(2));
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return "";
}
protected void onPostExecute(String s) {
// TODO: check this.exception
// TODO: do something with the feed
}
}
}
谁能解释一下会发生什么?
解决方案
您的代码应该因异常而中断,因为您正在从未创建它的线程中触摸您的视图。AsyncTasks 的解决方案是使用 doInBackground 内部的 publishProgress 和覆盖的 onProgressUpdated 中的句柄来调用回调,因为这段代码将在原始线程上,例如:
public SomeTask extends AsyncTask<DecodeResult, String, String> {
private Container container;
public someTask(Container container){
this.container = container;
}
public void doInBackground(String ... args) {
while (rs.next()) {
Log.i("OPERATOR IDENTIFIED", rs.getString(4));
publishProgress("OPERATOR IDENTIFIED " + rs.getString(2));
}
}
void onProgressUpdate(String step){
this.mCallBack.updateMyText(step);
}
}
如果您的应用程序没有崩溃,那么您需要确保任务是从您创建的侦听器启动的。调试一下看看。
Obs:请使用 Java 命名约定以及以小写字母开头的方法。
推荐阅读
- android - 自定义浮动操作按钮
- php - php localhost邮件没有收到
- java - 在 Java 中为以前的操作系统版本解析 DateTime
- c# - 使用 OleDbConnection、OleDbCommand 从 Excel 中读取 10000 多行
- python-3.x - 使用字典理解
- jpa - 如何从客户端访问 javax/persistence/?
- php - 当用户登录时显示“注销”按钮,当他不使用 PHP/MySQL 时显示“连接”
- http - 如何在我的网络服务器上支持古老的浏览器?
- c# - 将 SQL 查询转换为 Entity Framework Core 2.1
- .net - 查找在 Visual Studio 的调试器中显示的“外部”类的 .dll