【问题标题】:Progressbar and TextView updates in AndroidAndroid 中的 Progressbar 和 TextView 更新
【发布时间】:2017-05-14 01:54:38
【问题描述】:


我为我的问题创建了一个“小”示例。我有两个类:MainActivityBerechnung。类 Berechnung 计算一些应该花费一点时间的东西,仅用于测试进度条。
一、MainActivity:

package com.example.matthias.progressbar;


import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.os.Bundle;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;


public class MainActivity extends AppCompatActivity implements Runnable{


    Button btn;
    ProgressBar progress;
    TextView tv;

    Berechnung langeBerechnung;
    ArrayList<Integer> erg;
    boolean laeuftNoch;
    Handler handler = new Handler();

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

        btn = (Button)findViewById(R.id.button);
        progress = (ProgressBar) findViewById(R.id.progressBar);
        tv = (TextView) findViewById(R.id.textView);
    }



    @Override
    public void run() {
        int progressWert = 0;
        tv.setText("Berechnung gestartet.");
        while(laeuftNoch){
            progressWert = progressWert + 5;

            if(progressWert < 100){
                progress.setProgress(progressWert);
            }else {
                progressWert = 0;
                progress.setProgress(progressWert);
            }
        }
        tv.setText("Berechnung beendet.");
        progress.setProgress(100);
    }

    public void onClick(View v){
        handler.post(this);

        Callable<ArrayList<Integer>> call = new Berechnung();
        ExecutorService executor = Executors.newSingleThreadExecutor();
        Future<ArrayList<Integer>> future = executor.submit(call);

        try {
            ArrayList<Integer> erg = future.get();
            int index = ((Berechnung)call).getIndex();
            int grenze = ((Berechnung)call).getGrenze();
            Log.d("App", "Die längste Folge bis " + grenze + " entsteht für die Eingabe " + index + " und hat eine Länge von " + erg.size() + ".");
            ((Berechnung)call).ausgabe(erg);
        } catch (Exception e) {
            // Nothing
        }
        laeuftNoch = false;
    }


}

现在是第二课:

package com.example.matthias.progressbar;

import android.provider.Settings;
import android.telecom.Call;
import android.util.Log;

import java.util.ArrayList;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;

public class Berechnung implements Callable<ArrayList<Integer>> {

    ArrayList<Integer> list = new ArrayList<Integer>();
    ArrayList<ArrayList<Integer>> all = new ArrayList<ArrayList<Integer>>();
    int index;
    int grenze;

    public ArrayList<Integer> call(){
        all = new ArrayList<ArrayList<Integer>>();
        all.add(0, new ArrayList<Integer>());

        grenze = 35000;

        for(int i=1; i <= grenze; i++){
            Log.d("App", "Berechne collatz(" + i + ")");

            list = new ArrayList<Integer>();
            all.add(i, collatz(i));
        }

        int max = all.get(1).size();
        index = 1;
        for(int i=2; i <= grenze; i++){
            if(all.get(i).size() > max){
                max = all.get(i).size();
                index = i;
            }
        }


        return all.get(index);
    }


    public ArrayList<Integer> collatz(int n){
        list.add(n);
        if(n > 1) {
            if (n % 2 == 0) {
                n = n/2;
                return collatz(n);
            } else {
                n = 3*n + 1;
                return collatz(n);
            }
        }else{
            return list;
        }
    }

    public int getIndex(){
        return index;
    }

    public int getGrenze(){
        return grenze;
    }

    public void ausgabe(ArrayList<Integer> l){
        for(int i=0; i < l.size(); i++){
            Log.d("App", (i+1) + ".)\t" + l.get(i) + "");
        }
    }

}

我的问题可能在于 MainActivity。 TextView (tv) 和 ProgressBar (progress) 都不会更新。在第一步中,我使用了一个普通的线程来更改文本视图和进度条,但是我得到了一个来自错误线程异常的调用。然后我在一些网页上阅读,我需要一个处理程序来解决这个问题。但我不明白我必须如何使用它。

也许 xml 文件有助于解决这个问题:

    <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.matthias.progressbar.MainActivity">

    <ProgressBar
        android:layout_above="@+id/button"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/progressBar"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_marginBottom="65dp"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="180dp"
        android:text="Starte Berechnung"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:onClick="onClick" />

    <TextView
        android:text='Drücken Sie den Button "Starte Berechnung".'
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_marginTop="45dp"
        android:id="@+id/textView"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"
        android:textSize="16sp" />
</RelativeLayout>

我不确定是哪个班级出了问题,因此我把所有文件都给了你。 Berechnung 级也使用控制台输出,它阻塞了线程。或许这也是个问题(?)

请问,谁能帮我理解我的编程错误?

最好的问候,马蒂亚斯

【问题讨论】:

    标签: android multithreading android-progressbar


    【解决方案1】:

    对此我会采取完全不同的方法。

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        btn = (Button) findViewById(R.id.button);
        progress = (ProgressBar) findViewById(R.id.progressBar);
        tv = (TextView) findViewById(R.id.textView);
    }
    

    在这个onCreate 方法中,我会为按钮设置onClick 侦听器。 (btn.setOnClickListener(new OnClickListener)) 在这种方法中,您可以编写“运行”的东西。

    如果这不能真正回答您的问题,我可能误解了您。 那么这些东西有什么作用呢?

    @Override
    public void run() {
        int progressWert = 0;
        tv.setText("Berechnung gestartet.");
        while(laeuftNoch){
            progressWert = progressWert + 5;
    
            if(progressWert < 100){
                progress.setProgress(progressWert);
            }else {
                progressWert = 0;
                progress.setProgress(progressWert);
            }
        }
        tv.setText("Berechnung beendet.");
        progress.setProgress(100);
    }
    
    public void onClick(View v){
        handler.post(this);
    
        Callable<ArrayList<Integer>> call = new Berechnung();
        ExecutorService executor = Executors.newSingleThreadExecutor();
        Future<ArrayList<Integer>> future = executor.submit(call);
    
        try {
            ArrayList<Integer> erg = future.get();
            int index = ((Berechnung)call).getIndex();
            int grenze = ((Berechnung)call).getGrenze();
            Log.d("App", "Die längste Folge bis " + grenze + " entsteht für die Eingabe " + index + " und hat eine Länge von " + erg.size() + ".");
            ((Berechnung)call).ausgabe(erg);
        } catch (Exception e) {
            // Nothing
        }
        laeuftNoch = false;
    }
    

    无论如何你都没有谈论它们,我们需要你的“Berechnung”课程的哪一部分?另外,您遇到的确切问题是什么?

    编辑:

    所以也许它似乎没有更新给你,因为你的线程中没有sleep

    while(laeuftNoch) {
        progressWert = progressWert + 5;
    
        if(progressWert < 100){
            progress.setProgress(progressWert);
        } else {
            progressWert = 0;
            progress.setProgress(progressWert);
        }
    }
    

    这个while-loop 不需要时间!它并没有真正暂停还是我错过了什么?它在 1 毫秒内直接运行。所以你应该添加类似Thread.sleep(milliseconds) 的东西。 还有每次在for loop中分配列表的目的是什么?

    for(int i=1; i <= grenze; i++){
        Log.d("App", "Berechne collatz(" + i + ")");
    
        list = new ArrayList<Integer>();
        all.add(i, collatz(i));
    }
    

    【讨论】:

    • 您好,感谢您的回答。对不起。也许拥有 xml 文件很有用。我会立即改变这一点。在我说的XML文件中,方法onClick()会被调用,如果按钮会被点击,所以我是这样写的。我对 run 方法的想法是,进度条的最大值为 100,进度条应增加 +5 步,如果 progressValue 为 100,则它应该从 0 开始。这应该重复直到 Berechnung 中的计算 call()被终止。然后 TextView 也应该更新为“Berechnung bedet”。
    • 我在答案中添加了另外两个改进建议(在底部)。但我仍然没有完全理解你的目标/问题。
    • 你是对的,睡眠语句丢失了。我在我的代码中添加了这个,但我仍然有同样的问题。这是: 1.) 如果我点击按钮,TextView 应该直接变为 Berechnung gestartet 2.) 如果我点击按钮,Progressbar 应该增加到 100,然后跳转到 0 并再次增加, 等等。但相反,TextView 文本包含标准文本 Drücken Sie den Button "Starte Berechnung".(如您在 xml 文件中所见)。你现在是什么意思?
    猜你喜欢
    • 1970-01-01
    • 2017-08-15
    • 1970-01-01
    • 2012-09-24
    • 1970-01-01
    • 1970-01-01
    • 2017-05-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多