在Android的线程无限循环 [英] Android infinite loop in thread

查看:673
本文介绍了在Android的线程无限循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有我的用户界面和其他线程,那里是循环:

I have my UI and other Thread, where there is loop:

while(true){

}

我检查系统中的字符串值的变化,当变化,我通过pre-打开的套接字将消息发送到服务器。问题是,应用循环的时候,我的应用程序死机,和CPU负载非常高(约90%)。我知道,无限循环不得线程来完成,但你知道如何复制这种行为,没有使用无限循环?

I am checking changes of String value in the system, and when changes, I send message via pre-opened socket to the server. Problem is, when applying loop, my app freezes, and CPU load is very high (about 90 %). I know, infinite loop must not be done in thread, but do you know how to copy this behavior, not using infinite loop?

THX

主要code(onCreate方法):

    mProgressDialog = ProgressDialog.show(main.this, "loading","loading", true);
    c=new Client(this.getApplicationContext(), "192.168.0.121", 3333);
    c.start();

    CLIENT_MESSAGE="login user2 user2";
    synchronized(c){
        c.notify();
    }
    Client.zHandler.setEmptyMessage(119);


    mHandler = new Handler()
    {
        public void handleMessage(android.os.Message msg)
        {
            super.handleMessage(msg);

            switch (msg.what)
            {
                case 11:
                    Log.d("Logged in", "login");
                    mProgressDialog.dismiss();
                    break;
                case 12:    
                    Log.d("Logged out", "logout and end");
                    mProgressDialog.dismiss();
                    finish();
                    break;

                        }
                 }
          };

  @Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    switch (keyCode) {

    case KeyEvent.KEYCODE_BACK:
        CLIENT_MESSAGE="logout";
        synchronized (c) {
            c.notify();
        }
                    Client.zHandler.setEmptyMessage(129)
        break;
    default:

    }
    return true;
}

主题code(Client.java):

Thread Code (Client.java):

public Client(Context ctx, String hostname, int port){
    this.ctx=ctx;
    this.hostname=hostname;
    this.port=port;

    zHandler = new Handler()
    {
        public void handleMessage(android.os.Message msg)
        {
            super.handleMessage(msg);

            switch (msg.what)
            {
                case 119://login
                    Log.d("119", "case 119");
                    messageText=DropboxFileClientActivity.CLIENT_MESSAGE;
                    main.mHandler.sendEmptyMessage(11);
                    break;
                case 129://logout
                    messageText=DropboxFileClientActivity.CLIENT_MESSAGE;
                    main.mHandler.sendEmptyMessage(12);
                    break;
                case 100:   
                    break;

                        }
                 }
          };
}
    public void run(){
      try {
        clientSocket = new Socket(hostname, port);
        //inputLine = new BufferedReader(new InputStreamReader(System.in));

        os = new ObjectOutputStream (clientSocket.getOutputStream());

        is = new ObjectInputStream(clientSocket.getInputStream());
    }
    catch (UnknownHostException e) {
        Log.d("ERROR", "unknown host "+hostname); 
    }
    catch (IOException e) {
        Log.d("ERROR2", "no bind"+hostname);
        e.printStackTrace();
    }

    while (!isInterrupted()) {
        try{
            synchronized (this) {
                wait();
            }
        } catch (InterruptedException e) {
            break; // interrupting the thread ends it
        }
        if (clientSocket != null && os != null && is != null &&!messageText.equals("")) {
                messageText="";
                //sending message to server, getting reply and displaying it to the screen
            } 
      }//endwhile loop

   }


推荐答案

如果你的循环是,事实上,在一个单独的线程中运行,则问题是,它是CPU猪

If your loop is, indeed, running in a separate thread, then the problem is that it is a CPU hog.

而不是轮询,检查更改为字符串价值,这将是更好(如果你有过相关的code控制)来写一个setter触发来自其他线程的服务器更新(有,比方说,一个 / 通知协议)。

Rather than polling to check for changes to a String value, it would be much better (if you have control over the relevant code) to write a setter that triggers the server updates from the other thread (with, say, a wait/notify protocol).

即使你有轮询,你真的需要在CPU的速度呢?也许等到第二个会做什么?这将让你睡的时间休息。

Even if you have to poll, do you really need to do it at CPU speeds? Perhaps once a second would do? That would let you sleep the rest of the time.

最起码,叫 Thread.yield()通过循环每次。

At the very least, call Thread.yield() every time through the loop.

修改基于对信息的评论,你应该在后台线程等待:

EDIT Based on your comment to the post, you should be waiting in the background thread:

在你的后台线程

while (!isInterrupted()) {
    synchronized (this) {
        wait();
    } catch (InterruptedException e) {
        break; // interrupting the thread ends it
    }
    // read string and send it to the server
}

在你的事件处理程序:

public void onSomethingHappened(...) {
    // update the string
    synchronized (mThread) {
        mThread.notify();
    }
}

该字符串应标明挥发性除非读取和更新都在同一对象上同步的。

The string should be marked volatile unless the read and update are synchronized on the same object.

这篇关于在Android的线程无限循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆