首页 > 解决方案 > 从另一个类设置 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
    }
}
}

谁能解释一下会发生什么?

标签: javaandroid

解决方案


您的代码应该因异常而中断,因为您正在从未创建它的线程中触摸您的视图。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 命名约定以及以小写字母开头的方法。


推荐阅读