有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Android编码:ViewRootImpl$CalledFromErrorThreadException。[Noob]

06-13 17:29:30.750: W/dalvikvm(6257): threadid=13: thread exiting with uncaught exception (group=0xb1af0ba8)
06-13 17:29:30.780: E/AndroidRuntime(6257): FATAL EXCEPTION: Thread-251
06-13 17:29:30.780: E/AndroidRuntime(6257): Process: me.l0lkj.birthdaytimer, PID: 6257
06-13 17:29:30.780: E/AndroidRuntime(6257): 安卓.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
06-13 17:29:30.780: E/AndroidRuntime(6257):     at 安卓.view.ViewRootImpl.checkThread(ViewRootImpl.java:6094)
06-13 17:29:30.780: E/AndroidRuntime(6257):     at 安卓.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:857)
06-13 17:29:30.780: E/AndroidRuntime(6257):     at 安卓.view.ViewGroup.invalidateChild(ViewGroup.java:4320)
06-13 17:29:30.780: E/AndroidRuntime(6257):     at 安卓.view.View.invalidate(View.java:10935)
06-13 17:29:30.780: E/AndroidRuntime(6257):     at 安卓.view.View.invalidate(View.java:10890)
06-13 17:29:30.780: E/AndroidRuntime(6257):     at 安卓.widget.TextView.updateAfterEdit(TextView.java:7430)
06-13 17:29:30.780: E/AndroidRuntime(6257):     at  安卓.widget.TextView.handleTextChanged(TextView.java:7453)
06-13 17:29:30.780: E/AndroidRuntime(6257):     at 安卓.widget.TextView$ChangeWatcher.onTextChanged(TextView.java:9183)
06-13 17:29:30.780: E/AndroidRuntime(6257):     at 安卓.text.SpannableStringBuilder.sendTextChanged(SpannableStringBuilder.java:962)
06-13 17:29:30.780: E/AndroidRuntime(6257):     at 安卓.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:496)
06-13 17:29:30.780: E/AndroidRuntime(6257):     at 安卓.text.SpannableStringBuilder.append(SpannableStringBuilder.java:253)
06-13 17:29:30.780: E/AndroidRuntime(6257):     at 安卓.text.SpannableStringBuilder.append(SpannableStringBuilder.java:30)
06-13 17:29:30.780: E/AndroidRuntime(6257):     at 安卓.widget.TextView.append(TextView.java:3409)
06-13 17:29:30.780: E/AndroidRuntime(6257):     at 安卓.widget.TextView.append(TextView.java:3396)
06-13 17:29:30.780: E/AndroidRuntime(6257):     at me.l0lkj.birthdaytimer.Screen2.appendTextAndScroll(Screen2.java:180)
06-13 17:29:30.780: E/AndroidRuntime(6257):     at me.l0lkj.birthdaytimer.Screen2.access$1(Screen2.java:177)
06-13 17:29:30.780: E/AndroidRuntime(6257):     at  me.l0lkj.birthdaytimer.Screen2$ListenFromServer.run(Screen2.java:273)
06-13 17:29:58.330: I/Process(6257): Sending signal. PID: 6257 SIG: 9
06-13 17:33:57.960: D/dalvikvm(6315): GC_FOR_ALLOC freed 57K, 9% free 3567K/3920K,   paused 137ms, total 138ms
06-13 17:33:58.590: D/(6315): HostConnection::get() New Host Connection established  0xb91170e0, tid 6315
06-13 17:34:10.310: E/Første skjerm(6315): 10.0.0.59.1500.Anonym.123123
06-13 17:34:11.460: D/dalvikvm(6315): GC_FOR_ALLOC freed 19K, 8% free 3894K/4200K, paused 23ms, total 26ms
06-13 17:34:11.480: I/dalvikvm-heap(6315): Grow heap (frag case) to 6.498MB for 2536936-byte allocation
06-13 17:34:11.510: D/dalvikvm(6315): GC_FOR_ALLOC freed 1K, 5% free 6370K/6680K, paused 31ms, total 31ms
06-13 17:34:11.690: E/Andre skjerm(6315): 10.0.0.59.1500.Anonym.123123

我刚刚开始编码,目前正在开发Android聊天客户端,遇到了以下问题:

ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

我到处寻找,但似乎找不到任何解决这个问题的方法。简而言之,我想要的是:

  1. 这是一个很好的解释什么是这个问题以及如何解决它。发生原因等。

  2. 更正我的代码或帮助我找到解决方案。我读了一些有点明显的关于类可以访问和不能访问的内容,但我没有找到好的解决方案

我的代码有点乱,所以对此很抱歉(我还是个笨蛋,记住:))

package me.l0lkj.birthdaytimer;

import java.io.IOException; 
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.ArrayList;

import me.l0lkj.birthdaytimer.userlisthandler.UserInfo;
import 安卓.app.Activity;
import 安卓.content.Intent;
import 安卓.os.Bundle;
import 安卓.text.Layout;
import 安卓.text.method.ScrollingMovementMethod;
import 安卓.util.Log;
import 安卓.view.KeyEvent;
import 安卓.view.View;
import 安卓.view.inputmethod.EditorInfo;
import 安卓.widget.Button;
import 安卓.widget.ScrollView;
import 安卓.widget.TextView;
import 安卓.widget.TextView.OnEditorActionListener;

public class Screen2 extends Activity {

ArrayList<UserInfo> lastPlayerRegrex = new ArrayList<UserInfo>();

boolean running = false;

ScrollView chat_ScrollView;
TextView chat_text_chat;
TextView editText1;


String server;
int port;
String brukernavn;
String passord;


private ObjectInputStream sInput;   
private ObjectOutputStream sOutput;     
private Socket socket;

@Override
public void onCreate(Bundle savedInstanceState) {

    running = true;

    super.onCreate(savedInstanceState);
    setContentView(R.layout.screen2);

    Button btnSend = (Button) findViewById(R.id.btnSend);
    btnSend.setOnClickListener(new View.OnClickListener() {
        public void onClick(View view) {
            sendLine();
        }
    });

    Button btnClose = (Button) findViewById(R.id.btnClose);
    btnClose.setOnClickListener(new View.OnClickListener() {
        public void onClick(View view) {
            appendTextAndScroll("Forlater nå chatten!!");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            running = false;
            disconnect();
        }
    });

    Button btnList = (Button) findViewById(R.id.btnList);
    btnList.setOnClickListener(new View.OnClickListener() {
        public void onClick(View view) {
            //String test = "NAME:l0lkj;IP:10.0.0.39;SINCE:123422,NAME:asdasd;IP:10.0.0.234;SINCE:345678,NAME:ihkjhg;IP:10.04.6.7;SINCE:078273549234";

            sendMessage(new Message(Message.LIST_USERS, ""));   

            //ArrayList<UserInfo> users = Format(test);
            /*
             * Denne metoden skal sende inn en Message med syntaksen:
             *      
             *      new Message(4, "");
             *      
             * 
             * 
             */
            /*
            for(UserInfo user : users){
                long millis = user.getTid();

                int seconds = (int) (millis / 1000) % 60 ;
                int minutes = (int) ((millis / (1000*60)) % 60);
                int hours   = (int) ((millis / (1000*60*60)) % 24);

                String userdata = user.getName() + " IP:" + user.getIp() + " \n        Tid online: " + hours + " timer, " + minutes + " minutter og " + seconds + " sekunder.";
                appendTextAndScroll(userdata);
            }*/
        }
    });

    editText1 = (TextView) this.findViewById(R.id.editText1);
    editText1.setOnEditorActionListener(new OnEditorActionListener() {
        @Override
        public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
            boolean handled = false;
            if (actionId == EditorInfo.IME_ACTION_SEND) {
                sendLine();
                handled = true;
            }
            return handled;
        }
    });

    chat_text_chat = (TextView) this.findViewById(R.id.chat_text_chat);
    chat_text_chat.setMovementMethod(new ScrollingMovementMethod());

    Intent i = getIntent();

    server = i.getStringExtra("server");
    port = Integer.parseInt(i.getStringExtra("port"));
    brukernavn = i.getStringExtra("brukernavn");
    passord = i.getStringExtra("passord");

    Log.e("Andre skjerm", server + "." + port + "." + brukernavn + "." + passord);

    appendTextAndScroll("");

    this.start();

}

private void disconnect() {
    try { 
        if(sInput != null) sInput.close();
    }
    catch(Exception e) {}
    try {
        if(sOutput != null) sOutput.close();
    }
    catch(Exception e) {}
    try{
        if(socket != null) socket.close();
    }
    catch(Exception e) {}

    finish();

}

@SuppressWarnings("unused")
private void startConnection(String address, int port){

}

private void broadcastText(String text){
    //appendTextAndScroll(text);
    this.sendMessage(new Message(Message.MELDING, text));
    //sende til serveren
}

private void sendMessage(Message msg){
    try {
        sOutput.writeObject(msg);
    }
    catch(IOException e) {
        appendTextAndScroll("Exception writing to server: " + e);
    }
}

private void appendTextAndScroll(String text) {
    if(text.length() >= 1){
        if(chat_text_chat != null){
            chat_text_chat.append(text + "\n");
            final Layout layout = chat_text_chat.getLayout();
            if(layout != null){
                int scrollDelta = layout.getLineBottom(chat_text_chat.getLineCount() - 1) - chat_text_chat.getScrollY() - chat_text_chat.getHeight();
                if(scrollDelta > 0){
                    chat_text_chat.scrollBy(0, scrollDelta);
                }
            }
        }
    }
}

private void sendLine(){
    String text = editText1.getText().toString();
    editText1.setText("");
    broadcastText(text);
}

public ArrayList<UserInfo> Format(String rawFromServer){

    ArrayList<UserInfo> userObjects = new ArrayList<UserInfo>();

    String[] users = rawFromServer.split(",");
    for(String user : users){

        String name = null;
        String ip = null;
        long since = 0; 

        String[] keys = user.split(";");
        for(String key : keys){

            String[] keyAndAns = key.split(":");

            if(keyAndAns[0].equals("NAME")){
                name = keyAndAns[1];
            }

            if(keyAndAns[0].equals("IP")){
                ip = keyAndAns[1];
            }

            if(keyAndAns[0].equals("SINCE")){
                since = Long.parseLong(keyAndAns[1]);
            }

        }
        userObjects.add(new UserInfo(name, ip, since));
    }
    return userObjects;
}


public boolean start() {
    try {
        socket = new Socket(server, port);
    } 
    catch(Exception ec) {
        appendTextAndScroll("Feil under oppkobling til serveren:" + ec);
        return false;
    }

    String msg = "Kobling godtatt fra " + socket.getInetAddress() + ":" + socket.getPort();
    appendTextAndScroll(msg);

    try
    {
        sInput  = new ObjectInputStream(socket.getInputStream());
        sOutput = new ObjectOutputStream(socket.getOutputStream());
    }
    catch (IOException eIO) {
        appendTextAndScroll("Unntak ved ny Input/output strøm: " + eIO);
        return false;
    }

    new ListenFromServer().start();
    try {
        sOutput.writeObject((brukernavn + ":" + passord));
    } catch (IOException e) {
        e.printStackTrace();
    }

    return true;
}

class ListenFromServer extends Thread {

    public void run() {
        while(true) {
            try {

                String msg = (String) sInput.readObject();

                appendTextAndScroll(msg);
            }

            catch(IOException e) {
                appendTextAndScroll("Serveren har stengt koblingen: " + e);
                break;
            }
            catch(ClassNotFoundException e2) {}
        }
    }
}

}

谢谢你的回答

向亚历山大问好


共 (1) 个答案

  1. # 1 楼答案

    您正试图从后台线程更新视图,因此出现CalledFromWrongThreadException错误。这是不允许的

    在这种情况下,最简单的更改可能是修改appendTextAndScroll()本身,以确保它在UI线程中运行

    private void appendTextAndScroll(String text)
    {
        runOnUiThread(new Runnable()
        {
            public void run()
            {
                if(text.length() >= 1){
                    if(chat_text_chat != null){
                        chat_text_chat.append(text + "\n");
                        final Layout layout = chat_text_chat.getLayout();
                        if(layout != null){
                            int scrollDelta = layout.getLineBottom(chat_text_chat.getLineCount() - 1) - chat_text_chat.getScrollY() - chat_text_chat.getHeight();
                            if(scrollDelta > 0){
                                chat_text_chat.scrollBy(0, scrollDelta);
                            }
                        }
                    }
                }
            }
        });
    }