Java 线程中的Android bug

Java 线程中的Android bug,java,android,multithreading,Java,Android,Multithreading,我正在开发一个android问答应用程序,通过套接字连接到服务器。在客户端(Android设备),我在while循环中检查服务器(Java服务器)给出的答案。连接和接收答案都很顺利。问题是,在我的课堂上,检查答案有一个错误。为了提供更多信息,我将在此处包含部分代码: public void startClient(){ checkValue = new Thread(new Runnable(){ @Override public void run()

我正在开发一个android问答应用程序,通过套接字连接到服务器。在客户端(Android设备),我在while循环中检查服务器(Java服务器)给出的答案。连接和接收答案都很顺利。问题是,在我的课堂上,检查答案有一个错误。为了提供更多信息,我将在此处包含部分代码:

public void startClient(){

    checkValue = new Thread(new Runnable(){
        @Override
        public void run() {     
            try
            {
                final int PORT = 4444;
                final String HOST = "192.168.1.118";
                Socket SOCK = new Socket(HOST, PORT);
                Log.e("success", "You connected to: " + HOST);

                quizClient = new QuizClient(SOCK);

                //Send the groupname to the list
                PrintWriter OUT = new PrintWriter(SOCK.getOutputStream());
                OUT.println(groupName);
                OUT.flush();

                Thread X = new Thread(quizClient);
                X.start();

                connected = true;


            }
            catch(Exception X)
            {
                Log.e("connection error", "Error: ", X);
            }       
        }
    });

    checkValue.start(); 

}

public void testvalue(){

    Thread thread = new Thread(new Runnable(){
        @Override
        public void run() {
            try {
                while(true){
                    if(message != null && !message.matches("")){
                        Thread.sleep(1000);
                        Log.e("receive", message);
                        buffer = message;
                        message = "";

                        Message msg = new Message();
                        String textTochange = buffer;
                        msg.obj = textTochange;
                        mHandler.sendMessage(msg);
                        Thread.sleep(3000);
                    }

                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });

    thread.start();

}

Handler mHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {

        String text = (String)msg.obj;
        //call setText here

        //String[] myStringArray = new String[]; 
        value.clear();

        String[] items = text.split(";");
        for (String item : items)
        {
            value.add(item);
            Log.e("message", item);
            //System.out.println("item = " + item);
        }

        if(value.get(0).equals("1")){

            questionGroup.setVisibility(View.INVISIBLE);
            sendAnswer.setVisibility(View.INVISIBLE);
            answer.setVisibility(View.INVISIBLE);
            question.setText("");


            question.setText(value.get(2));
            rad1.setText(value.get(3));
            rad2.setText(value.get(4));
            rad3.setText(value.get(5));
            rad4.setText(value.get(6));

            questionGroup.setVisibility(View.VISIBLE);
            sendAnswer.setVisibility(View.VISIBLE);


        } else if (value.get(0).equals("2")){

            questionGroup.setVisibility(View.INVISIBLE);
            sendAnswer.setVisibility(View.INVISIBLE);
            answer.setVisibility(View.INVISIBLE);

            question.setText("");
            question.setText(value.get(2));
            answer.setVisibility(View.VISIBLE);
            sendAnswer.setVisibility(View.VISIBLE);


        } else
        {
            questionGroup.setVisibility(View.INVISIBLE);
            sendAnswer.setVisibility(View.INVISIBLE);
            answer.setVisibility(View.INVISIBLE);

            question.setText(text);
        }


    }
};

@Override
protected void onStop() 
{

    if (connected == true){
        try {
            quizClient.DISCONNECT();
        } catch (IOException e) {
            e.printStackTrace();
        }   
    }

    if(checkValue != null)
    {
        checkValue.interrupt();
    }

    super.onStop();
    closeApplication();

}
因此,我创建了这个类的一个新实例(在这里我实际检查传入的数据流)

因此,我认为缺陷会持续存在于以下类别中:

public void testvalue(){

    Thread thread = new Thread(new Runnable(){
        @Override
        public void run() {
            try {
                while(true){
                    if(message != null && !message.matches("")){
                        Thread.sleep(1000);
                        Log.e("receive", message);
                        buffer = message;
                        message = "";
我在这里做的是创建一个线程并检查“message”是否不等于null。消息来自另一个类:

public void RECEIVE()
{

    if(INPUT.hasNext())
    {
        String MESSAGE = INPUT.nextLine();

        if(MESSAGE.contains("#?!"))
        {

        }
        else
        {
            QuizActivity.message = MESSAGE;
现在,大多数情况下,这是很好的,但有两个问题。当我离开页面时,它与服务器断开连接(正常工作),我返回页面并再次连接到服务器,但这次我在屏幕上没有得到任何值(接收是okj,但出于另一个原因,它在我的处理程序中不正常)。在一段时间后还将获取indexoutofboundexception:

question.setText(value.get(2));
第二个问题在程序运行时发生。有些时候,当界面正确接收输入时,我也无法在界面上获得值

所以我的猜测是,我的线程读入值的解决方案并不是处理它的最佳方式。所以现在我问那些有更多经验的人,我能做些什么使这项工作没有重大问题?您需要知道连接的工作原理,我在QuizClient类中获得了值。所以问题应该在我的主课上

我的oncreate类:

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

    selectgroep = (Spinner) findViewById(R.id.groepen);
    questionGroup = (RadioGroup) findViewById(R.id.QuestionGroup);
    sendAnswer = (Button) findViewById(R.id.sendAnswer);

    rad1 = (RadioButton) findViewById(R.id.radio0);
    rad2 = (RadioButton) findViewById(R.id.radio1);
    rad3 = (RadioButton) findViewById(R.id.radio2);
    rad4 = (RadioButton) findViewById(R.id.radio3);

    answer = (EditText) findViewById(R.id.textanswer);

    questionGroup.setVisibility(View.INVISIBLE);
    sendAnswer.setVisibility(View.INVISIBLE);
    answer.setVisibility(View.INVISIBLE);


    try {
        connect();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    //Code na het drukken op de knop
    startserver = (Button) findViewById(R.id.startserver);
    startserver.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            startClient();
            getID();
            testvalue();
        }

});

    sendAnswer.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // Stuur antwoord door en sluit alles af 
            questionGroup.setVisibility(View.INVISIBLE);
            sendAnswer.setVisibility(View.INVISIBLE);
            answer.setVisibility(View.INVISIBLE);
            answer.setText("");

            rad1.setChecked(true);
            rad1.setText("");
            rad2.setText("");
            rad3.setText("");
            rad4.setText("");

            question.setText("Wachten op server ... ");

        }
    });

}
提前谢谢大家,,
Thomas Thooft

你在Oncreate of main类中添加了什么?我在帖子中添加了Oncreate类。
而(true){RECEIVE();}
你将在这里创建很多负载。。。忙着等待不是个好主意。如果你想定期检查,最好使用定时器。我不知道什么最适合你,但C2DM也可能是一个合适的解决方案,因为这样你就不需要不断地轮询服务器。另外,如果你选中“消息”=空&!message.matches(“”)``这里没有其他选项。当值为null或“”时,您也将忙于等待。(除此之外,与睡眠同步不是我的最爱。此外,当消息的值发生变化时,您可以在此处使用计时器或使用回调接口,但这实际上取决于您的目标)您应该使用AsycTask,这样繁忙的任务就不会在主线程上执行。
    @Override
protected void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_quiz);

    selectgroep = (Spinner) findViewById(R.id.groepen);
    questionGroup = (RadioGroup) findViewById(R.id.QuestionGroup);
    sendAnswer = (Button) findViewById(R.id.sendAnswer);

    rad1 = (RadioButton) findViewById(R.id.radio0);
    rad2 = (RadioButton) findViewById(R.id.radio1);
    rad3 = (RadioButton) findViewById(R.id.radio2);
    rad4 = (RadioButton) findViewById(R.id.radio3);

    answer = (EditText) findViewById(R.id.textanswer);

    questionGroup.setVisibility(View.INVISIBLE);
    sendAnswer.setVisibility(View.INVISIBLE);
    answer.setVisibility(View.INVISIBLE);


    try {
        connect();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    //Code na het drukken op de knop
    startserver = (Button) findViewById(R.id.startserver);
    startserver.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            startClient();
            getID();
            testvalue();
        }

});

    sendAnswer.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // Stuur antwoord door en sluit alles af 
            questionGroup.setVisibility(View.INVISIBLE);
            sendAnswer.setVisibility(View.INVISIBLE);
            answer.setVisibility(View.INVISIBLE);
            answer.setText("");

            rad1.setChecked(true);
            rad1.setText("");
            rad2.setText("");
            rad3.setText("");
            rad4.setText("");

            question.setText("Wachten op server ... ");

        }
    });

}