Android:在处理程序中设置文本,但TextView中的文本未更改。

huangapple go评论83阅读模式
英文:

Android: SetText in handler doesn't change text in TextView

问题

我有一个连接到蓝牙并显示接收到的信息的应用程序。
在按下返回键时,活动并没有被销毁,我可以返回到该活动,并且一切都保持不变。该活动在后台收集数据,一切正常。
我有一个按钮,当按下时,会销毁所有活动(包括显示数据的活动)。
当我尝试再次创建该活动时,数据继续到达,我仍然可以处理它并将其写入文件,但在用户界面中不会显示出来。似乎在第二次创建活动后,处理程序中的setText函数不起作用(在处理程序之外的地方setText确实起作用)。

布尔值synced在活动第二次创建时为true。
这是OnCreate方法:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_admin);
    loading_panel = findViewById(R.id.loadingPanel);
    loading_panel.setVisibility(View.GONE);
    connectionButton = (Button) findViewById(R.id.connection_button);

    gsrTextView = (TextView) findViewById(R.id.gsr_textview);
    emgTextView = (TextView) findViewById(R.id.emg_textview);
    adxlTextView = (TextView) findViewById(R.id.adxl_textview);
    fsrTextView = (TextView) findViewById(R.id.fsr_textview);
    textviews_set=true;
    if(synced)
    {
        setConnected(currMac);
        manageConnection();
        Button sync_button = (Button) findViewById(R.id.sync_button);
        sync_button.setText(R.string.synced_text);
    }
    // 更多的代码
}

OnBackPressed方法的实现:

@Override
public void onBackPressed() {
    Intent i = new Intent(AdminActivity.this, MainActivity.class);
    i.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
    startActivity(i);
}

这是处理程序的一部分:

@SuppressLint("HandlerLeak")
public final Handler handler = new Handler() {
    @Override
    public void handleMessage(@NonNull Message msg) {
        super.handleMessage(msg);

        switch (msg.what) {
            // 其他情况的大量代码
            case READ_SUCCESS:
                String s = (String) msg.obj;
                showData(s);

                break;
        }
    }
};

这是showData的一部分:

private void showData(String s) {
    // 待办事项:1.解析JSON;2.在TextView上显示数据(JSON组件)

    try {
        //Log.d(LOG_TAG, "the new string is " + s);
        JSONObject json = new JSONObject(s);

        // 收集传感器测量值
        String gsrMeasure = json.getString("gsr");
        String emgMeasure = json.getString("emg");
        String adxlMeasure = json.getString("adxl");
        String fsrMeasure = json.getString("fsr");
        String time_str = json.getString("time");

        // 显示数据
        if(textviews_set) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Log.d(LOG_TAG, "ABOUT TO SET TEXT");
                    gsrTextView.setText(gsrMeasure);
                    emgTextView.setText(emgMeasure);
                    adxlTextView.setText(adxlMeasure);
                    fsrTextView.setText(fsrMeasure);
                }
            });
        }
        // 更多的代码
    } catch (JSONException e) {
        e.printStackTrace();
    }
}

我甚至确保在UI线程上运行setText,尽管在第一次运行活动时没有使用runOnUiThread。我还认为可能是在findViewByID调用之前处理程序被调用,但我使用了一个名为textviews_set的布尔变量来确保它不会发生。

值得一提的是,当我第一次创建活动时,蓝牙设备未连接,因此处理程序未运行,因此问题很有可能出在这里。 我只是不确定确切的位置,或者如何解决它。

英文:

I have an app that connects to bluetooth and displays information received.
when pressing back, the activity isn't killed and I can go back to the activity and everything is the same. The activity collects the data in the background and everything is okay
I have a button, that when pressed, kills all activities (including the activity that displays the data).
When I try to create that activity again, the data keeps coming, and I can still handle it and write it to a file, but it won't show it in the UI. It seems the setText function in the handler doesn't work after the activity is created the second time (setText does work outside of the handler).

The boolean value synced is true if the activity is created a second time.
This is OnCreate

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_admin);
        loading_panel = findViewById(R.id.loadingPanel);
        loading_panel.setVisibility(View.GONE);
        connectionButton = (Button) findViewById(R.id.connection_button);

        gsrTextView = (TextView) findViewById(R.id.gsr_textview);
        emgTextView = (TextView) findViewById(R.id.emg_textview);
        adxlTextView = (TextView) findViewById(R.id.adxl_textview);
        fsrTextView = (TextView) findViewById(R.id.fsr_textview);
        textviews_set=true;
        if(synced)
        {
            setConnected(currMac);
            manageConnection();
            Button sync_button = (Button) findViewById(R.id.sync_button);
            sync_button.setText(R.string.synced_text);
        }
        // more code
    }

Implementation of OnBackPressed:

@Override
    public void onBackPressed() {
        Intent i = new Intent(AdminActivity.this, MainActivity.class);
        i.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
        startActivity(i);
    }

This is (part of) the handler:

@SuppressLint("HandlerLeak")
    public final Handler handler = new Handler() {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);

            switch (msg.what) {
                //a lot of code for other cases
                case READ_SUCCESS:
                    String s = (String) msg.obj;
                    showData(s);
                    
                    break;
            }
        }
    }

This is (part of) showData:
private void showData(String s) {
// todo: 1.parse the json; 2.show data (json components) on the textViews

    try {
        //Log.d(LOG_TAG, "the new string is " + s);
        JSONObject json = new JSONObject(s);

        // Collect the sensors measurements
        String gsrMeasure = json.getString("gsr");
        String emgMeasure = json.getString("emg");
        String adxlMeasure = json.getString("adxl");
        String fsrMeasure = json.getString("fsr");
        String time_str = json.getString("time");

        // Show the data
        if(textviews_set) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Log.d(LOG_TAG, "ABOUT TO SET TEXT");
                    gsrTextView.setText(gsrMeasure);
                    emgTextView.setText(emgMeasure);
                    adxlTextView.setText(adxlMeasure);
                    fsrTextView.setText(fsrMeasure);
                }
            });
        }
        //more code
    }
}

I even made sure that I'm running the setText on UI thread even though it works on the first run of the activity without the runOnUiThread
I also thought that maybe the handler is called before the findViewByIDs are called but I used a boolean variable textviews_set to make sure it doesn't happen

It is worth mentioning that when I create the activity for the first time, the bluetooth device isn't connected and thus the handler isn't running, so there's a really good chance that the problem lies there. I just don't know exactly where, or how to solve it.

答案1

得分: 1

我找出了问题所在,如果有人遇到同样的问题。我将所有的TextView声明为非静态的,因此当第二次创建活动时,由于某种原因处理程序仍然引用第一个实例活动的TextView。
我所需要做的就是将类中的TextView声明为static,这样当我第二次创建活动时,这些TextView已经被声明并且引用了XML中的实际TextView。

英文:

I found out what the problem was, if anyone gets stuck with the same issue.
I declared all the textviews as non-static, thus when creating the activity the second time, for some reason the handler still referred to the textviews of the first instance of the activity.
All I had to do was declare the textviews in the class as static, so when I create the activity for the second time, the textviews are already declared and refer to the actual textviews in the xml.

答案2

得分: 0

根据提供的信息,以下是最佳建议。

所以在 onCreate() 中尝试在 textviews_set=true; 之前执行以下操作:

gsrTextView.setText(" ");
emgTextView.setText(" "); 
adxlTextView.setText(" "); 
fsrTextView.setText(" "); 

希望这能解决问题。

参考:

英文:

Based on the information provide the follow is the best suggestion.

So try the following in onCreate() before textviews_set=true;

   gsrTextView.setText(" ");
   emgTextView.setText(" "); 
   adxlTextView.setText(" "); 
   fsrTextView.setText(" "); 

Hope this solves issue.

Reference:

huangapple
  • 本文由 发表于 2020年6月29日 03:05:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/62627054.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定