How to program outside the main UI thread

戏子无情 提交于 2019-12-12 16:17:15

问题


I don't know if a UI thread exists by default, how to create it if not, or how to tell when I'm "in" it where it begins and ends if so. How do I make sure PacketListener isn't part of the main UI thread?

I keep running into this NetworkOnMainThreadException. I understand that means that I'm trying to do something in the main UI thread that should have its own separate thread. However, I can't find much to tell me HOW to actually do that.

I had thought that the MainActivity class would BE the UI thread, since, well, I had a UI and it worked. However, I've created a seperate class that implements Runnable, and put the network connection stuff in there, and am still getting the exception, so it's still part of the main thread, yes? I can see that MainActivity doesn't extend Thread, so maybe that was a dumb assumption. I don't have the feeling that anything will change if I add another class that implements Runnable/extends Thread. Will it?


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();
        }
    }
}

EDIT:

My latest attempt, trying to follow this page's example, has gone the route of most of my attempts, and broke the app completely. SendAnother is a testing method bound to a button:

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");
                }
            });
        }
    });
}

I think next I'll finally try AsyncTask. I no longer much care if it's "dirty".


回答1:


ui thread is main thread. you know about current thread by

Thread.currentThread().getName();

sorry i didn't read your whole question but you have to do blocking proccess in another thread than mainThread.

there are many ways to do that : AsyncTask , Services , ExecutorService and RxJava . and which one to pick depends on your need

this link would be helpful :)




回答2:


Your last method is correct, except the thread isn't started yet. So you need to call the start():

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");
        }
      });
    }
  }).start();
}



回答3:


I'm still not sure I like AsyncTask for this project, so if someone can offer advice or a link to a tutorial to use Handler or Runnable, PLEASE post it!

Strictly speaking though, this at least finally lets me do stuff outside the UI thread, and that was the question. Sooo, for what it's worth to any others having this problem, here's what first worked for me.

public class MainActivity extends AppCompatActivity {
    ArrayAdapter<String> adapter;
    private static final int PORT= 8888;
    private static final int TIMEOUT_MS = 500;

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

        ArrayList<String> listItems = new ArrayList<>();
        ListView listview = (ListView) findViewById(R.id.lvMain);
        adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, listItems);
        listview.setAdapter(adapter);

        UpdateView task = new UpdateView();
        task.execute();

        //just to show these parts are in different threads
        String temp = Thread.currentThread().getName();
        adapter.add("onCreate: " + temp);
    }

    private class UpdateView extends AsyncTask<URL, Integer, Long> {
        protected Long doInBackground(URL... urls) {
            //just to show these parts are in different threads
            String temp = Thread.currentThread().getName();
            adapter.add("UpdateView: " + temp);

            byte[] buf = new byte[256];
            byte[] ipAddress = {(byte)192,(byte)168,0,1};

            try {
                InetAddress address = InetAddress.getByAddress(ipAddress);

                String message = "\"xyz\"";
                DatagramSocket socket = new DatagramSocket(PORT);
                DatagramPacket packet = new DatagramPacket(message.getBytes(), message.length(), address, PORT);
                socket.send(packet);

                packet = new DatagramPacket(buf, buf.length);
                socket.receive(packet);
            }
            catch(IOException e) {
                adapter.add("IO Exception: " + e.toString() );
                e.printStackTrace();
            }

            adapter.notifyDataSetChanged();
            return 0L;
        }
    }
}


来源:https://stackoverflow.com/questions/46369961/how-to-program-outside-the-main-ui-thread

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!