无法运行我的Android应用程序

时间:2013-03-02 00:13:41

标签: android

我正在尝试在服务器和客户端之间建立聊天应用程序,但由于这行代码,应用程序无法运行:message =(String)input.readObject(); 因为最初,inputStream为null!任何人都可以帮忙吗?这是我的代码

package com.example.test;

import java.io.BufferedReader;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OptionalDataException;
import java.net.Socket;


import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.os.StrictMode;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends Activity {

    private Button send;
    private Button connect;
    private EditText userText;
    private TextView chatWindow;

    private String serverIP;
    private ObjectOutputStream output;
    private ObjectInputStream input;
    private String message = "";
    private Socket connection;

    @SuppressLint({ "NewApi", "NewApi", "NewApi" })
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (android.os.Build.VERSION.SDK_INT > 9) {
            StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
            StrictMode.setThreadPolicy(policy);
          }

        serverIP = "192.168.1.4";
        //userText.setEnabled(false);
        send = (Button)findViewById(R.id.button1);
        connect = (Button)findViewById(R.id.button2);
        chatWindow =(TextView)findViewById(R.id.textView1); 
        userText = (EditText)findViewById(R.id.editText1); 
        userText.setHint("Enter your message here");

        connect.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v) {


                //connect to the server
                try{
                    connectToServer();
                    setupStreams();

                }catch(EOFException eofException){
                    showMessage("\n client terminated the connection");
                }catch(IOException ioException){
                    ioException.printStackTrace();
                }
            }
        });

        send.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                String message = userText.getText().toString();
                sendMessage(message);
                userText.setText("");   

            }
        });

        while(true){
            try{
                message = (String) input.readObject(); 
                showMessage("\n" + message + " NULL ");
                chatWindow.refreshDrawableState(); 
            }catch(ClassNotFoundException classNotFoundException){
                showMessage("\n I don't know that object type");
            }
            catch(NullPointerException e){
                e.printStackTrace();
            }
            catch (OptionalDataException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    } // end of onCreate


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }


    //connect to the server
        private void connectToServer() throws IOException {
            showMessage("Attempting connection... \n");
            connection = new Socket( "192.168.1.4", 6789);
            showMessage("Connected to " + connection.getInetAddress().getHostName() );
        }

        //setup streams to send and receive messages
        private void setupStreams() throws IOException{
            output = new ObjectOutputStream(connection.getOutputStream());
            output.flush();
            input = new ObjectInputStream(connection.getInputStream());
            showMessage("\n Your streams are now good to go! \n ");
        }

        //whileChatting with server
        private void whileChatting() throws IOException{

                try{
                    message = (String) input.readObject(); 
                    showMessage("\n" + message + " NULL ");
                    chatWindow.refreshDrawableState(); 
                }catch(ClassNotFoundException classNotFoundException){
                    showMessage("\n I don't know that object type");
                }

        }

        //close the streams and sockets
        private void closeCrap(){
            showMessage("\n closing crap down");
            ableToType(false);
            try{
                output.close();
                input.close();
                connection.close();
            }catch(IOException ioException){
                ioException.printStackTrace();
            }
        }

        // gives user permission to type into the text box
        private void ableToType(final boolean tof){
            userText.setEnabled(tof);
        }

        // send messages to server
        private void sendMessage(String message){
            try{
                output.writeObject("CLIENT - " + message);
                output.flush();
                showMessage("\nCLIENT - " + message);
            }catch(IOException ioException){
                chatWindow.append("\n somethine messed up sending message!");
            }
        }

        //change/update chatWindow
        private void showMessage(final String m){
            chatWindow.append(m);
            chatWindow.refreshDrawableState();
        }

} // end of class MainActivity

2 个答案:

答案 0 :(得分:2)

您的代码肯定没有遵循任何良好的UI准则:您正在主(UI)线程上进行网络操作,您在onCreate()中有一个无限循环。如果没有任何崩溃,Android应该实际提供强制关闭您的应用程序。现在,可能导致您面临的null问题:

只有按一下按钮才会调用

setupStreams()。但是,您的while (true)循环位于onCreate()的根目录中。这意味着只要创建并设置了单击侦听器,循环就会运行,尝试从input读入并因为setupStreams()未被调用而失败。

所以请不要取消StrictMode - 它是 help ,以及从事件驱动的角度来看你的代码(“一旦发生X,然后执行Y”)。并且还摆脱了主(UI)线程中的循环。循环适用于控制台窗口,但是使用UI(具有自己的复杂生命周期),如果不冻结很多东西,就不能这样做。

答案 1 :(得分:1)

doInBackground()的{​​{1}}中完成所有网络任务,然后更新AsyncTask中的UI个变量。像

这样的东西
onPostExecute()

以下是 AsyncTask

的文档

要考虑的另一件事是你在不同的地方使用变量 public class TalkToServer extends AsyncTask<String, String, String> { @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected void onProgressUpdate(String... values) { super.onProgressUpdate(values); } @Override protected String doInBackground(String... params) { //do your work here return something; } @Override protected void onPostExecute(String result) { super.onPostExecute(result); // do something with data here-display it or send to mainactivity } ,这可能会导致你的问题。看起来你已将它定义为成员变量,然后将其定义为其他方法的局部变量。您不希望以这种方式重用相同的变量名称。请勿在同一message

中多次定义String message