Я создаю «маленький» пример для моего вопроса. У меня два класса: MainActivity и Berechnung . Класс Berechnung вычисляет некоторые вещи, которые должны стоить немного времени, только для тестирования progressbar.
Во-первых, главное:
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) + "");
}
}
}
Моя проблема, наверное,в Главном. Ни TextView (tv), ни ProgressBar (progress) не будут обновлены. На первом шаге я использовал обычный поток, который изменяет textview и progressbar, но я получаю вызов от неправильного исключения потока . Затем я прочитал на некоторых веб-страницах, что мне нужен обработчик для этой проблемы. Но я не понимаю, как я должен это использовать.
Возможно, xml-файл помогает для этой проблемы:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
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-class использует также консольный выход, который заблокировал поток. Может быть, это тоже проблема (?)
Пожалуйста, кто-нибудь может помочь мне понять мои прогрессирующие ошибки?
С наилучшими пожеланиями, Matthias
Я бы подошел к этому совсем по-другому.
В этом
onCreate
методе я бы поставилonClick
прослушиватель для кнопки.(
btn.setOnClickListener(new OnClickListener)
)В этом методе вы можете написать свой» run » материал.
Если это на самом деле не ответ на ваш вопрос, я мог неправильно понять вас.
Так что же делают эти вещи?
В любом случае, вы не говорили о них, и для какой части нам нужен ваш «Berechnung» класс? Также какова точная проблема у вас есть?
РЕДАКТИРОВАТЬ:
Поэтому, возможно, вам кажется, что он не обновляется, потому что у вас нет
sleep
в потоке.Это
while-loop
не займет много времени! Он не делает паузу или я что-то упускаю? Он бежит прямо до конца внутри как 1 госпожа. Поэтому вы должны добавить что-то вродеThread.sleep(milliseconds)
.А также какова цель присвоения списка каждый раз
for loop
?