简体   繁体   English

Android编码:ViewRootImpl $ CalledFromWrongThreadException。 [菜鸟]

[英]Android coding: ViewRootImpl$CalledFromWrongThreadException. [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): android.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 android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6094)
06-13 17:29:30.780: E/AndroidRuntime(6257):     at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:857)
06-13 17:29:30.780: E/AndroidRuntime(6257):     at android.view.ViewGroup.invalidateChild(ViewGroup.java:4320)
06-13 17:29:30.780: E/AndroidRuntime(6257):     at android.view.View.invalidate(View.java:10935)
06-13 17:29:30.780: E/AndroidRuntime(6257):     at android.view.View.invalidate(View.java:10890)
06-13 17:29:30.780: E/AndroidRuntime(6257):     at android.widget.TextView.updateAfterEdit(TextView.java:7430)
06-13 17:29:30.780: E/AndroidRuntime(6257):     at  android.widget.TextView.handleTextChanged(TextView.java:7453)
06-13 17:29:30.780: E/AndroidRuntime(6257):     at android.widget.TextView$ChangeWatcher.onTextChanged(TextView.java:9183)
06-13 17:29:30.780: E/AndroidRuntime(6257):     at android.text.SpannableStringBuilder.sendTextChanged(SpannableStringBuilder.java:962)
06-13 17:29:30.780: E/AndroidRuntime(6257):     at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:496)
06-13 17:29:30.780: E/AndroidRuntime(6257):     at android.text.SpannableStringBuilder.append(SpannableStringBuilder.java:253)
06-13 17:29:30.780: E/AndroidRuntime(6257):     at android.text.SpannableStringBuilder.append(SpannableStringBuilder.java:30)
06-13 17:29:30.780: E/AndroidRuntime(6257):     at android.widget.TextView.append(TextView.java:3409)
06-13 17:29:30.780: E/AndroidRuntime(6257):     at android.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

I just startet coding and am currently working on my chat client for Android and got this problem: 我只是开始编码,目前正在使用Android的聊天客户端,但遇到了以下问题:

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

I have searched around but cant seem to find anything that solves this problem. 我四处搜寻,但似乎找不到任何能解决此问题的东西。 What I want in short terms: 短期我想要的是:

  1. A good explanation of what this problem is and how to get around it. 一个很好的解释,这个问题是什么以及如何解决它。 Why it occurs etc. 为什么会发生等等

  2. Correct my code or help me find a solution to it. 更正我的代码或帮助我找到解决方案。 I read what was a bit obvious to about what classes can and can not acces that, but I found no good solution. 我阅读了有关哪些类可以接受和不能接受的内容的一些明显了解,但是我没有找到好的解决方案。

I have a bit messy code, so sorry about that ( I'm still a noob, remeber that :) ) 我的代码有点凌乱,对此感到抱歉(我仍然是菜鸟,请记住:))

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 android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.text.Layout;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.ScrollView;
import android.widget.TextView;
import android.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) {}
        }
    }
}

}

Thank you for answer; 谢谢你的答案;

Best regards Alexander 最好的问候亚历山大

You're getting a CalledFromWrongThreadException error because you're trying to update views from a background thread. 由于尝试从后台线程更新视图,因此出现CalledFromWrongThreadException错误。 That is not allowed. 那是不允许的。

In this case, the easiest change would probably be to modify appendTextAndScroll() itself to make sure it runs in the UI thread. 在这种情况下,最简单的更改可能是修改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);
                        }
                    }
                }
            }
        }
    });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Android - ViewRootImpl$CalledFromWrongThreadException - Android - ViewRootImpl$CalledFromWrongThreadException android.view.viewrootimpl $ fromwrongthreadexception android java - android.view.viewrootimpl$calledfromwrongthreadexception android java Android动态文本更新-ViewRootImpl $ CalledFromWrongThreadException - Dynamic Text Update for Android - ViewRootImpl$CalledFromWrongThreadException 计时器导致ViewRootImpl $ CalledFromWrongThreadException吗? - Timer causing ViewRootImpl$CalledFromWrongThreadException? android.view.ViewRootImpl $ CalledFromWrongThreadException:只有创建视图层次结构的原始线程才能触摸其视图 - android.view.ViewRootImpl$CalledFromWrongThreadException:Only the original thread that created a view hierarchy can touch its views 为什么我收到异常ViewRootImpl $ CalledFromWrongThreadException? - Why i'm getting exception ViewRootImpl$CalledFromWrongThreadException? 当我按下按钮时,出现错误ViewRootImpl $ CalledFromWrongThreadException - When my button is pressed, I get the error ViewRootImpl$CalledFromWrongThreadException ViewRootImpl不在Android SDK中 - ViewRootImpl not in Android SDK CalledFromWrongThreadException在Android上执行JUnit测试 - CalledFromWrongThreadException exercising JUnit tests on Android Android Thread.start()CalledFromWrongThreadException - Android Thread.start() CalledFromWrongThreadException
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM