Android 如何在主UI线程外编程

Android 如何在主UI线程外编程,android,multithreading,udp,networkonmainthread,Android,Multithreading,Udp,Networkonmainthread,我不知道UI线程在默认情况下是否存在,如果不存在,如何创建它,或者如何告诉我何时“进入”它,如果存在,它从哪里开始和结束。如何确保PacketListener不是主UI线程的一部分 我一直遇到这个networkMainThreadException。我理解这意味着我正在尝试在主UI线程中做一些事情,这些线程应该有自己的独立线程。然而,我找不到多少东西来告诉我如何真正做到这一点 我原以为MainActivity类将是UI线程,因为我有一个UI,而且它工作正常。然而,我已经创建了一个单独的类来实现R

我不知道UI线程在默认情况下是否存在,如果不存在,如何创建它,或者如何告诉我何时“进入”它,如果存在,它从哪里开始和结束。如何确保
PacketListener
不是主UI线程的一部分

我一直遇到这个networkMainThreadException。我理解这意味着我正在尝试在主UI线程中做一些事情,这些线程应该有自己的独立线程。然而,我找不到多少东西来告诉我如何真正做到这一点

我原以为MainActivity类将是UI线程,因为我有一个UI,而且它工作正常。然而,我已经创建了一个单独的类来实现Runnable,并将网络连接的东西放在其中,并且仍然得到异常,所以它仍然是主线程的一部分,是吗?我可以看出MainActivity并没有扩展线程,所以这可能是一个愚蠢的假设。如果我添加了另一个实现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();
    }
}

我想接下来我将最终尝试
AsyncTask
。我不再关心它是否“脏”。ui线程是主线程。你知道当前的线程

Thread.currentThread().getName();
很抱歉,我没有阅读您的全部问题,但您必须在主线程之外的另一个线程中执行阻塞过程

有很多方法可以做到这一点:AsyncTask、Services、ExecutorService和RxJava。 选择哪一个取决于你的需要


可能会有帮助:)

您的上一个方法是正确的,只是线程尚未启动。因此,您需要调用
start()


我仍然不确定我是否喜欢这个项目的AsyncTask,所以如果有人可以提供建议或链接到教程来使用Handler或Runnable,请发布它

严格来说,这至少让我可以在UI线程之外做一些事情,这就是问题所在。Sooo,对于任何其他有这个问题的人来说,这都是值得的,这是我首先要做的

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;
        }
    }
}
public类MainActivity扩展了AppCompatActivity{
阵列适配器;
专用静态最终int端口=8888;
专用静态最终整数超时\u MS=500;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ArrayList listItems=新的ArrayList();
ListView ListView=(ListView)findViewById(R.id.lvMain);
adapter=new ArrayAdapter(这个,android.R.layout.simple\u list\u item\u 1,listItems);
setAdapter(适配器);
UpdateView任务=新建UpdateView();
task.execute();
//只是为了说明这些部件在不同的线程中
String temp=Thread.currentThread().getName();
adapter.add(“onCreate:+temp”);
}
私有类UpdateView扩展异步任务{
受保护的长doInBackground(URL…URL){
//只是为了说明这些部件在不同的线程中
String temp=Thread.currentThread().getName();
adapter.add(“UpdateView:+temp”);
字节[]buf=新字节[256];
字节[]ipAddress={(字节)192,(字节)168,0,1};
试一试{
InetAddress=InetAddress.getByAddress(ipAddress);
字符串消息=“\”xyz\”;
DatagramSocket套接字=新DatagramSocket(端口);
DatagramPacket=新的DatagramPacket(message.getBytes(),message.length(),地址,端口);
socket.send(包);
数据包=新数据包(基本单位,基本单位长度);
套接字接收(数据包);
}
捕获(IOE异常){
add(“IO异常:+e.toString());
e、 printStackTrace();
}
adapter.notifyDataSetChanged();
返回0升;
}
}
}

Ok,但是如何创建一个新线程,与UI线程分离?我认为创建一个实现Runnable的类可以做到这一点,但事实并非如此。我不知道我是否做错了什么,或者这是否是一个可行的方法。长期的答案是谷歌“java多线程”,然后在Android中,你能推荐一个教程吗?我至少感谢你的帖子,因为这似乎是其他人都不愿意做的事情(包括关于我的其他问题…)尽管如此,我还是非常感谢一个建议的链接,因为我用这个搜索字符串找到的东西还没有比我自己找到的东西更有用。我会尽我所能帮助人们:)。。。抱歉耽搁了,我不是在线的啊,说得好。虽然没有改变,但它现在仍然拒绝运行,甚至没有足够远的距离给我
NetworkOnMainThreadException
我启动线程的原因。好吧,即使我的备份也不起作用,而且我开始尝试让某些东西重新工作的全新项目也被破坏了。我不知道发生了什么,但也许我应该暂时搁置这个问题,等我把这个问题解决了……好了-_-
Thread.currentThread().getName();
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();
}
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;
        }
    }
}