来自 AsyncTask 块 UI 的线程
我有 MainActivity,它在执行名为“Datensammlung”的 AsyncTask 之前执行一些工作。该任务通过不同的类启动一些其他线程。它们都实现了 Runnable 并且工作正常。两个用于与服务器通信(TCP 连接),有些用于监听事件/生成随机数(间隔 10 秒)。
现在我想显示每个线程工作的一些值(我总是使用同步)。 当我只启动侦听器线程时,“onProgressUpdate”可能会被调用 5 次,直到结束更新 UI。当我启动另外两个线程进行通信时,什么也没有显示。
尽管我使用了 asynctasks,为什么我的 UI 仍然被阻止?
有人有主意吗?谢谢你!
Fabian
AsyncTask:Datensammlung
protected Void doInBackground(String[]... params) {
// TODO Auto-generated method stub
while (true) {
int counter = 0;
ArrayList<String> texte = new ArrayList<String>();
String test = "";
for (Input i : this.Dataliste) {
String text = " "+i.variablenName + ": "+String.valueOf(i.getAbstrakterWert())+"\n";
texte.add(text);
test += text;
// Log.e("TEXT ", text);
// counter ++;
}
publishProgress(test);
Log.e("TEXT", test);
test = "";
counter ++;
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO: handle exception
}
}
}
@Override
protected void onProgressUpdate(String... listen) {
TextView t = this.viewList.get(0);
Log.e("hier isser", "1");
for (String r : listen) {
t.setText(r);
Log.e("hier isser", r);
}
}
我的通信类之一:
package kommunikation;
public class SensorAdapter implements Runnable{
String iP;
int port;
Socket socket;
ObjectOutputStream out;
ObjectInputStream in;
ArrayList<Nachricht> nachrichtenliste = new ArrayList<Nachricht>();
Handler handler = new Handler();
// Konstruktor
public SensorAdapter(String iP, int port) {
super();
this.iP = iP;
this.port = port;
}
public boolean initialisiere_sensor(ArrayList<Textobjekt> pObjekte){
try {
socket = new java.net.Socket(iP,port);
// serialisiere alle Inputs und sende die Daten an das FW
out = new ObjectOutputStream(new ObjectOutputStream(socket.getOutputStream()));
out.writeObject(pObjekte);
out.flush();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return true;
}
public void run() {
try {
while (true) {
if (!nachrichtenliste.isEmpty()) {
PrintWriter printWriter =new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
Nachricht speicher = nachrichtenliste.get(0);
String senden = schreibe_nachricht(speicher);
printWriter.print(senden);
printWriter.flush();
synchronized (nachrichtenliste) {
nachrichtenliste.remove(speicher);
}
}
try {
Thread.sleep(500);
handler.post(this);
} catch (InterruptedException e) {
// TODO: handle exception
}
}
} catch (Exception e) {
// TODO: handle exception
}
}
通信线程开始的地方:
public class Kommunikator implements Callback{
ArrayList<Input> objektliste;
ArrayList<Textobjekt> textliste;
boolean update_erforderlich = false;
public boolean bereit = false;
private Verbindungsdaten verbindungsdaten;
private SensorAdapter sadapter;
private ClientAdapter cadapter;
Thread sensorfred;
Thread clientfred;
// Konstruktor
public Kommunikator(ArrayList<Input> plist, ArrayList<Textobjekt> ptextliste){
boolean check;
boolean cCheck;
this.objektliste = plist;
this.textliste = ptextliste;
// startet die kommunikation
this.sadapter = new SensorAdapter("192.168.2.106", 1111);
this.cadapter = new ClientAdapter("192.168.2.106", 2222,this);
check = sadapter.initialisiere_sensor(ptextliste);
if (check ) {
sensorfred = new Thread(sadapter);
sensorfred.start();
}
// client darf wirklcih erst nach dem sensorlayer starten
cCheck = cadapter.initialisiere_client(ptextliste);
if (cCheck) {
clientfred = new Thread(cadapter);
clientfred.start();
}
this.bereit = true;
}
// kann vom Sensor aufgerufen werden um die updates an das framework zu senden
public void melde(Nachricht na){
Nachricht speicher =null;
for (Nachricht n : this.sadapter.nachrichtenliste) {
if (n.getName().equals(na.getName())) {
speicher = n;
}
}
// lösche die alte nachricht
if (speicher != null) {
int index = sadapter.nachrichtenliste.indexOf(speicher);
sadapter.nachrichtenliste.remove(index);
}
synchronized (sadapter.nachrichtenliste) {
this.sadapter.nachrichtenliste.add(na);
}
}
public void melde_Abstract(String name, int Version, float wert){
// hier synchronized rein???
for (Input i : objektliste) {
if (i.variablenName.equals(name)) {
// mache Versionscheck und schreibe dann dort den wert
synchronized (i) {
i.setAbstrakterWert(wert);
}
}
}
}
I have MainActivity which does some Work before it Executes an AsyncTask called "Datensammlung". This task starts some other Threads via different classes. All of Them implement Runnable and work correct. Two are for communication with a Server(TCP Connections) and some are listening for Events/ generating random numbers(Intervall 10 seconds).
Now i want to display some Values every thread works on(i always use synchronized).
When i only start the Listener-Threads, "onProgressUpdate" is called maybe 5 times until it ends updating the UI. When i start the two other threads for Communication nothing is displayed ever.
Why is my UI still blocked although i used asynctasks?
Anyone got an idea? Thank you!
Fabian
AsyncTask:Datensammlung
protected Void doInBackground(String[]... params) {
// TODO Auto-generated method stub
while (true) {
int counter = 0;
ArrayList<String> texte = new ArrayList<String>();
String test = "";
for (Input i : this.Dataliste) {
String text = " "+i.variablenName + ": "+String.valueOf(i.getAbstrakterWert())+"\n";
texte.add(text);
test += text;
// Log.e("TEXT ", text);
// counter ++;
}
publishProgress(test);
Log.e("TEXT", test);
test = "";
counter ++;
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO: handle exception
}
}
}
@Override
protected void onProgressUpdate(String... listen) {
TextView t = this.viewList.get(0);
Log.e("hier isser", "1");
for (String r : listen) {
t.setText(r);
Log.e("hier isser", r);
}
}
One of my Communication Class:
package kommunikation;
public class SensorAdapter implements Runnable{
String iP;
int port;
Socket socket;
ObjectOutputStream out;
ObjectInputStream in;
ArrayList<Nachricht> nachrichtenliste = new ArrayList<Nachricht>();
Handler handler = new Handler();
// Konstruktor
public SensorAdapter(String iP, int port) {
super();
this.iP = iP;
this.port = port;
}
public boolean initialisiere_sensor(ArrayList<Textobjekt> pObjekte){
try {
socket = new java.net.Socket(iP,port);
// serialisiere alle Inputs und sende die Daten an das FW
out = new ObjectOutputStream(new ObjectOutputStream(socket.getOutputStream()));
out.writeObject(pObjekte);
out.flush();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return true;
}
public void run() {
try {
while (true) {
if (!nachrichtenliste.isEmpty()) {
PrintWriter printWriter =new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
Nachricht speicher = nachrichtenliste.get(0);
String senden = schreibe_nachricht(speicher);
printWriter.print(senden);
printWriter.flush();
synchronized (nachrichtenliste) {
nachrichtenliste.remove(speicher);
}
}
try {
Thread.sleep(500);
handler.post(this);
} catch (InterruptedException e) {
// TODO: handle exception
}
}
} catch (Exception e) {
// TODO: handle exception
}
}
The Place where the Communication-Thread gets started:
public class Kommunikator implements Callback{
ArrayList<Input> objektliste;
ArrayList<Textobjekt> textliste;
boolean update_erforderlich = false;
public boolean bereit = false;
private Verbindungsdaten verbindungsdaten;
private SensorAdapter sadapter;
private ClientAdapter cadapter;
Thread sensorfred;
Thread clientfred;
// Konstruktor
public Kommunikator(ArrayList<Input> plist, ArrayList<Textobjekt> ptextliste){
boolean check;
boolean cCheck;
this.objektliste = plist;
this.textliste = ptextliste;
// startet die kommunikation
this.sadapter = new SensorAdapter("192.168.2.106", 1111);
this.cadapter = new ClientAdapter("192.168.2.106", 2222,this);
check = sadapter.initialisiere_sensor(ptextliste);
if (check ) {
sensorfred = new Thread(sadapter);
sensorfred.start();
}
// client darf wirklcih erst nach dem sensorlayer starten
cCheck = cadapter.initialisiere_client(ptextliste);
if (cCheck) {
clientfred = new Thread(cadapter);
clientfred.start();
}
this.bereit = true;
}
// kann vom Sensor aufgerufen werden um die updates an das framework zu senden
public void melde(Nachricht na){
Nachricht speicher =null;
for (Nachricht n : this.sadapter.nachrichtenliste) {
if (n.getName().equals(na.getName())) {
speicher = n;
}
}
// lösche die alte nachricht
if (speicher != null) {
int index = sadapter.nachrichtenliste.indexOf(speicher);
sadapter.nachrichtenliste.remove(index);
}
synchronized (sadapter.nachrichtenliste) {
this.sadapter.nachrichtenliste.add(na);
}
}
public void melde_Abstract(String name, int Version, float wert){
// hier synchronized rein???
for (Input i : objektliste) {
if (i.variablenName.equals(name)) {
// mache Versionscheck und schreibe dann dort den wert
synchronized (i) {
i.setAbstrakterWert(wert);
}
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
当您使用 Handler.post() 时,它将在 UI 线程上执行 runnable(如果处理程序是在 UI 线程中创建的)。因此,当您执行 handler.post(this) 时,您实际上是在 UI 线程上进行所有通信。
When you use Handler.post() it will execute runnable on UI thread (if handler was created in UI thread). So when you do handler.post(this) you actually do all your communication on UI thread.