1

您好我正在创建一个以安卓设备为客户端的客户端-服务器应用程序。在我的应用程序中,我的客户端(android 设备)发送一个请求,服务器对该请求作出响应。我注意到任何导致主线程等待的方法都必须在不同的线程上完成。我正在尝试这样做,但在我的情况下使用ThreadExecutor. 我实现了一个辅助 Runnable类,我将其传递ObjectInputStream给但由于某种原因,它始终为空。我在这里检查了许多问题,但似乎大多数问题都是关于如何从一项活动传递到另一项活动。但是,我想从我的助手传给activity我的助手class,但我不确定该怎么做。

这是我的代码,我希望它更有意义。

    package com.dozie.service;
    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.io.StringWriter;
    import java.net.Socket;
    import java.net.UnknownHostException;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;

    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    import javax.xml.parsers.ParserConfigurationException;
    import javax.xml.transform.Transformer;
    import javax.xml.transform.TransformerException;
    import javax.xml.transform.TransformerFactory;
    import javax.xml.transform.dom.DOMSource;
    import javax.xml.transform.stream.StreamResult;

    import org.w3c.dom.Document;
    import org.w3c.dom.Element;

    import com.dcloud.common.Event;
    import com.dcloud.common.Message;

    import android.os.Bundle;
    import android.app.Activity;
    import android.content.Intent;
    import android.text.Editable;
    import android.text.TextWatcher;
    import android.util.Log;
    import android.view.Menu;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.TextView;

    public class RegisterActivity extends Activity {

        private Button registerButton;
        private Button cancelButton;
        private TextView errorText;
        private EditText firstnameField, lastnameField, passwordField, cPasswordField, usernameField;
        private String fname, lname, pword, cPword, uname;
        private Socket socket;
        private TextWatcher fnameWatcher, lnameWatcher, pwordWatcher, cPwordWatcher, unameWatcher;
        protected ObjectOutputStream os;
        protected ObjectInputStream is;
        private ExecutorService threadPool;
        private RegisterWorker worker;
        public static final String PASSWORD_PATTERN = "((?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).{6,20})";
        public static final String USERNAME_PATTERN = "^[A-z0-9_-]{5,20}$"; 
        public static final String TAG = RegisterActivity.class.getName();
        public static final int SAMEFIRSTUSER = 100; //same first name and username,
        public static final int SAMELASTUSER = 200;  //same last name and username
        public static final int SAMEPASSFIRST = 300; //same password and firstname
        public static final int SAMEPASSLAST = 400; //same password and lastname
        public static final int SAMEPASSUSER = 500; //same password and username
        public static final int USERNOTMATCH = 600; //username does not match
        public static final int PASSNOTMATCH = 700; //password does not match
        public static final int CPASS_DIFF = 800; //password and confirm password are different
        public static final int GOODINPUT = 1; //every input is good

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_register);
            registerButton = (Button) findViewById(R.id.register_id);
            cancelButton = (Button) findViewById(R.id.cancel_id);
            firstnameField = (EditText) findViewById(R.id.firstname_id);
            lastnameField = (EditText) findViewById(R.id.lastname_id);
            passwordField = (EditText) findViewById(R.id.rpassword_id);
            cPasswordField = (EditText) findViewById(R.id.rcpassword_id);
            usernameField = (EditText) findViewById(R.id.rusername_id);
            errorText = (TextView) findViewById(R.id.errorText_id);
            fname="";lname="";pword="";cPword="";uname="";

            //initialize TextWatchers
            initializeWatchers();
            // add TextWatchers
            firstnameField.addTextChangedListener(fnameWatcher);
            lastnameField.addTextChangedListener(lnameWatcher);
            passwordField.addTextChangedListener(pwordWatcher);
            cPasswordField.addTextChangedListener(cPwordWatcher);
            usernameField.addTextChangedListener(unameWatcher);
            cancelButton.setOnClickListener(new OnClickListener()
            {

                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    firstnameField.setText("");
                    lastnameField.setText("");
                    passwordField.setText("");
                    cPasswordField.setText("");
                    usernameField.setText("");
                    setResult(RESULT_CANCELED);
                    finish();
                }

            });
        }

        @Override
        public void onStart()
        {
            super.onStart();
            Log.d(TAG, "onStart()");
            Intent intent = getIntent();
            final String address = intent.getStringExtra("ipAddress");
            final int port = intent.getIntExtra("port", 6060);
            threadPool = Executors.newFixedThreadPool(2);
            new Thread(new Runnable()
            {

                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    try {
                        Log.i(TAG, "Trying to Connect to "+ address + " on " + port);
                        socket = new Socket(address, port);
                        Log.i(TAG, "Connection established!");
                        os = new ObjectOutputStream(new DataOutputStream(socket.getOutputStream()));
                        is = new ObjectInputStream(new DataInputStream(socket.getInputStream()));

                        Log.i(TAG, "Client connected to server.");
                    } catch (UnknownHostException e) {
                        // TODO Auto-generated catch block
                        Log.e(TAG, "UnknownHostException", e);
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        Log.e(TAG, "I/O Exception", e);
                    }

                }

            }).start();
    //      threadPool.execute(worker = new RegisterWorker(is));;
        }


        @Override
        public void onPause()
        {
            super.onPause();
            Log.d(TAG, "onPause()");
            threadPool.shutdown();
            Message out = new Message("disconnect");
            out.setRequest(Event.Request.DISCONNECT);
            try {
                os.writeObject(out);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                Log.e(TAG, "I/O Exception", e);
            }
            finally
            {
                try {
                    is.close();
                    os.close();
                    socket.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            Log.i(TAG, "socket closed");
        }

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

        public int validateInput(String [] input)
        {
            String firstname = input[0];
            String lastname = input[1];
            String password = input[2];
            String cpassword = input[3];
            String username = input[4];

            Pattern pattern = Pattern.compile(PASSWORD_PATTERN);
            Matcher matcher = pattern.matcher(password);
            Pattern p = Pattern.compile(USERNAME_PATTERN);
            Matcher m = p.matcher(username);
            if(firstname.equals(username))
                return RegisterActivity.SAMEFIRSTUSER;
            if(lastname.equals(username))
                return RegisterActivity.SAMELASTUSER;
            if(firstname.equals(password))
                return RegisterActivity.SAMEPASSFIRST;
            if(lastname.equals(password))
                return RegisterActivity.SAMEPASSLAST;
            if(password.equals(username))
                return RegisterActivity.SAMEPASSUSER;
            if(!password.equals(cpassword))
                return RegisterActivity.CPASS_DIFF;
            if(!matcher.matches())
                return RegisterActivity.PASSNOTMATCH;
            if(!m.matches())
                return RegisterActivity.USERNOTMATCH;
            return RegisterActivity.GOODINPUT;
        }

        public void registerUser(View v)
        {
            String [] input = getUserInformation();
            int result = validateInput(input);
            switch(result)
            {
            case RegisterActivity.GOODINPUT:
                Intent info = new Intent();
                info.putExtra("username", input[4]);
                registerUser(input);
                if(worker.getServerResponse() != null)
                {
                    if(worker.getServerResponse().getResponse() == Event.Response.REQUEST_SUCCESSFUL)
                    {
                        threadPool.shutdown();
                        setResult(RESULT_OK, info);
                        finish();
                        Log.i(TAG, "registerUser(): data input successful!");
                    }
                    else if(worker.getServerResponse().getResponse() == Event.Response.REQUEST_UNSUCCESSFUL)
                    {
                        threadPool.execute(worker);
                        Log.i(TAG, "registerUser(): data input unsuccessful!");
                    }
                }

                break;
            case RegisterActivity.SAMEFIRSTUSER:
                errorText.setText("username should not be the same as firstname");
                Log.i(TAG, "registerUser(): username same as firstname");break;
            case  RegisterActivity.SAMELASTUSER:
                errorText.setText("username should not be the same as lastname");
                Log.i(TAG, "registerUser(): username same as lastname");break;
            case  RegisterActivity.SAMEPASSFIRST:
                errorText.setText("password should not be the same as firstname");
                Log.i(TAG, "registerUser(): password same as firstname");break;
            case RegisterActivity.SAMEPASSLAST:
                errorText.setText("password should not be the same as lastname");
                Log.i(TAG, "registerUser(): password same as lastname");break;
            case RegisterActivity.SAMEPASSUSER:
                errorText.setText("password should not be the same as username");
                Log.i(TAG, "registerUser(): password same as username");break;
            case RegisterActivity.CPASS_DIFF:
                errorText.setText("password and confirm password are not the same");
                Log.i(TAG, "registerUser(): password and confirm password not the same");break;
            case RegisterActivity.PASSNOTMATCH:
                errorText.setText("password format wrong. Password should contain 6-20 characters\n" +
                        "characters containing at least 1 digit, 1 lower case alphabet and 1 upper case character");
                Log.i(TAG, "registerUser(): password format not correct");break;
            case RegisterActivity.USERNOTMATCH:
                errorText.setText("username format wrong. username should contain 5-20 characters " +
                        "and should have to special characters");
                Log.i(TAG, "registerUser(): username format not correct");break;
            default:
                Log.i(TAG, "registerUser(): Code not handled");break;
            }
        }

        public String []  getUserInformation()
        {
            String firstname = firstnameField.getText().toString();
            String lastname = lastnameField.getText().toString();
            String password = passwordField.getText().toString();
            String cpassword = cPasswordField.getText().toString();
            String username = usernameField.getText().toString();
            String [] input = {firstname, lastname, password, cpassword, username};
            return input;
        }

        public void initializeWatchers()
        {
            fnameWatcher = new TextWatcher()
            {

                @Override
                public void afterTextChanged(Editable s) {
                    // TODO Auto-generated method stub
                    fname = firstnameField.getText().toString();
                    fname.trim();
                    updateButton();
                }

                @Override
                public void beforeTextChanged(CharSequence s, int start, int count,
                        int after) {
                    // TODO Auto-generated method stub

                }

                @Override
                public void onTextChanged(CharSequence s, int start, int before,
                        int count) {
                    // TODO Auto-generated method stub

                }

            };

            lnameWatcher = new TextWatcher()
            {
                @Override
                public void afterTextChanged(Editable s) {
                    // TODO Auto-generated method stub
                    lname = lastnameField.getText().toString();
                    lname.trim();
                    updateButton();
                }

                @Override
                public void beforeTextChanged(CharSequence s, int start, int count,
                        int after) {
                    // TODO Auto-generated method stub

                }

                @Override
                public void onTextChanged(CharSequence s, int start, int before,
                        int count) {
                    // TODO Auto-generated method stub

                }
            };

            pwordWatcher = new TextWatcher()
            {
                @Override
                public void afterTextChanged(Editable s) {
                    // TODO Auto-generated method stub
                    pword = passwordField.getText().toString();
                    pword.trim();
                    updateButton();
                }

                @Override
                public void beforeTextChanged(CharSequence s, int start, int count,
                        int after) {
                    // TODO Auto-generated method stub

                }

                @Override
                public void onTextChanged(CharSequence s, int start, int before,
                        int count) {
                    // TODO Auto-generated method stub

                }
            };

            cPwordWatcher = new TextWatcher()
            {
                @Override
                public void afterTextChanged(Editable s) {
                    // TODO Auto-generated method stub
                    cPword = cPasswordField.getText().toString();
                    cPword.trim();
                    updateButton();
                }

                @Override
                public void beforeTextChanged(CharSequence s, int start, int count,
                        int after) {
                    // TODO Auto-generated method stub

                }

                @Override
                public void onTextChanged(CharSequence s, int start, int before,
                        int count) {
                    // TODO Auto-generated method stub

                }

            };

            unameWatcher = new TextWatcher()
            {
                @Override
                public void afterTextChanged(Editable s) {
                    // TODO Auto-generated method stub
                    uname = usernameField.getText().toString();
                    uname.trim();
                    updateButton();
                }

                @Override
                public void beforeTextChanged(CharSequence s, int start, int count,
                        int after) {
                    // TODO Auto-generated method stub

                }

                @Override
                public void onTextChanged(CharSequence s, int start, int before,
                        int count) {
                    // TODO Auto-generated method stub

                }
            };
        }


        public void updateButton()
        {
            boolean enabled = fname.length()>0 && lname.length()>0 && pword.length()>0 
                    && cPword.length()>0 && uname.length() >0;
                    registerButton.setEnabled(enabled);
        }

        public void registerUser(String [] input)
        {

            try {
                DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
                DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
                Document doc = docBuilder.newDocument();

                Element rootElement = doc.createElement("Register");
                doc.appendChild(rootElement);

                Element user = doc.createElement("user");
                rootElement.appendChild(user);

                Element firstname = doc.createElement("firstname");
                firstname.appendChild(doc.createTextNode(input[0]));
                user.appendChild(firstname);

                Element lastname = doc.createElement("lastname");
                lastname.appendChild(doc.createTextNode(input[1]));
                user.appendChild(lastname);

                Element password = doc.createElement("password");
                password.appendChild(doc.createTextNode(input[2]));
                user.appendChild(password);

                Element username = doc.createElement("username");
                username.appendChild(doc.createTextNode(input[4]));
                user.appendChild(username);

                StringWriter writer = new StringWriter();
                TransformerFactory transformerFactory = TransformerFactory.newInstance();
                Transformer transformer = transformerFactory.newTransformer();
                transformer.transform(new DOMSource(doc), new StreamResult(writer));
                String content = writer.toString();

                Message out = new Message(content);
                out.setRequest(Event.Request.REGISTER);
                os.writeObject(out);
                Log.d(TAG, "registerUser(): Register message sent");


            } catch (ParserConfigurationException e) {
                // TODO Auto-generated catch block
                Log.e(TAG, "onActivityReturn(): ParserConfigurationException error", e);
            }  catch (TransformerException e) {
                // TODO Auto-generated catch block
                Log.e(TAG, "onActivityReturn(): TransformerException error", e);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                Log.e(TAG, "onActivityReturn(): IOException error", e);
            } 
        }
    }

<p>And for my runnable class</p>






package com.dozie.service;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.OptionalDataException;

import android.util.Log;

import com.dcloud.common.Event;
import com.dcloud.common.Message;



public class RegisterWorker implements Runnable{

    private ObjectInputStream is;
    private Message in;
    public static final String TAG = RegisterWorker.class.getName();

    public RegisterWorker(ObjectInputStream is)
    {
        this.is = is;
        if(this.is == null)
            System.out.println("null");

    }
    @Override
    public void run() {
        // TODO Auto-generated method stub
        try {
            while((in = (Message) is.readObject())!=null)
            {
                if(in.getResponse() == Event.Response.REQUEST_SUCCESSFUL)
                {
                    Log.d(TAG, "Login Response: "+in.getMessage());
                }
                else if(in.getResponse() == Event.Response.REQUEST_UNSUCCESSFUL)
                {
                    Log.d(TAG, "Login Response: "+in.getMessage());
                    //give reason for rejection
                }
            }
        } catch (OptionalDataException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public Message getServerResponse()
    {
        return in;
    }

}
4

2 回答 2

1

简单的方法是创建一个静态变量并将值分配给它。其他解决方案是创建一个对象,其中包含要在可运行和活动之间携带的值列表,并在创建实例时传递此对象

在你的情况下,它可能看起来像

MyObject myObject = null;

public RegisterWorker(ObjectInputStream is, MyObject myObject)
    {
        this.is = is;
          this.myObject=myObject;
        if(this.is == null)
            System.out.println("null");

    }

处理完成后,您添加一个方法,您可以在其中返回对象,以便您的活动类可以调用该方法并将其用于进一步处理。

public MyObject getMyObject(){
retunr myObject
}

但是您可以尝试的另一种方法是使用 AsyncTask。您可以在哪里提及创建 AsyncTask 时要返回的内容。

于 2012-12-01T06:34:05.717 回答
1

我认为您正在编写的代码比它需要的要复杂得多。如果您想将变量传递给 a Thread,这是我认为您正在尝试做的事情,只需执行以下操作:

public Worker extends AsyncTask<Arguments, Void, Void> {
  // method names may be slightly incorrect, writing this from memory
  public void runInBackground(Arguments...args) {
    // do what you want to do in the background
  }
}

然后开始你的线程:

Arguments args = new Arguments(arg1, arg2); // whatever you want to pass along
new Worker().execute(args);

WhereArguments可以是任何类,以此为例。

希望这可以帮助。

于 2012-12-01T10:39:50.557 回答