Я не знаю, существует ли поток пользовательского интерфейса по умолчанию, как его создать, если нет, или как сообщить когда я «в нем», где он начинается и заканчивается, если это так. Как убедиться, что PacketListener
не является частью основного потока пользовательского интерфейса?
Я продолжаю сталкиваться с этим NetworkOnMainThreadException. Я понимаю, что это означает, что я пытаюсь сделать что-то в основном потоке пользовательского интерфейса, который должен иметь свой отдельный поток. Тем не менее, я не могу найти много, чтобы сказать мне, КАК на самом деле это сделать.
Я думал, что класс MainActivity БУДЕТ потоком пользовательского интерфейса, поскольку у меня был пользовательский интерфейс, и он работал. Тем не менее, я создал отдельный класс, который реализует Runnable, и поместил туда материалы для сетевого подключения, и я все еще получаю исключение, так что это все еще часть основного потока, да? Я вижу, что MainActivity не расширяет Thread, так что, возможно, это было глупое предположение. У меня нет ощущения, что что-то изменится, если я добавлю еще один класс, который реализует Runnable/extends Thread. Будет ли он?
MainActivity.java
public class MainActivity extends AppCompatActivity {
ArrayList<String> listItems;
ArrayAdapter<String> adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listItems = new ArrayList<>();
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, listItems);
ListView listview = (ListView) findViewById(R.id.listview);
listview.setAdapter(adapter);
(new Thread(new PacketListener(adapter))).run();
}
}
PackageListener.java:
public class PacketListener implements Runnable {
ArrayAdapter<String> adapter;
public PacketListener(ArrayAdapter<String> adapter) {
this.adapter = adapter;
}
public void run() {
byte[] buf = new byte[256];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
try {
DatagramSocket socket = new DatagramSocket();
socket.receive(packet);
}
catch(Exception e) {
adapter.add("Exception: " + e.toString() );
e.printStackTrace();
}
catch(Error e) {
adapter.add("Unspecified Error: " + e.toString() );
e.printStackTrace();
}
}
}
РЕДАКТИРОВАТЬ:
Моя последняя попытка, попытка следовать примеру этой страницы , пошел по пути большинства моих попыток и полностью сломал приложение. SendAnother
— метод тестирования, привязанный к кнопке:
public void sendAnother(View view) {
adapter.add("button clicked");
new Thread(new Runnable() {
public void run() {
listview.post(new Runnable() {
public void run() {
adapter.add("inside worker thread");
}
});
}
});
}
Думаю, в следующий раз наконец-то попробую AsyncTask
. Меня больше не волнует, "грязный" ли он.