我有这个Android代码:
private class myTask extends AsyncTask<String, String, String> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected String doInBackground(String... params) {
try {
client = new Socket("192.168.1.2", 4444);
oos = new ObjectOutputStream(client.getOutputStream());
ois = new ObjectInputStream(client.getInputStream());
oos.writeUTF("LOGIN");
oos.flush();
String emailText = email.getText().toString();
oos.writeUTF(emailText);
oos.flush();
String passwordText = password.getText().toString();
oos.writeUTF(passwordText);
oos.flush();
string = ois.readUTF();
}catch (ConnectException e){
return "Host not found";
}catch (IOException e) {
return "Exception Caught";
}
return null;
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if ("Host not found".equalsIgnoreCase(result)){
Toast.makeText(getApplicationContext(), "Host not found" ,Toast.LENGTH_LONG).show();
}else if("Exception Caught".equalsIgnoreCase(result)){
Toast.makeText(getApplicationContext(), "Connection error" ,Toast.LENGTH_LONG).show();
}else{
Toast.makeText(getApplicationContext(), "Connection established" ,Toast.LENGTH_LONG).show();
}
Toast.makeText(getApplicationContext(), string ,Toast.LENGTH_LONG).show();
if(string.equals("Login successfully Done!")){
startActivity(new Intent(Login.this, User.class));
}
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
register = (TextView)findViewById(R.id.register);
login = (Button)findViewById(R.id.login);
email = (EditText)findViewById(R.id.email);
password = (EditText)findViewById(R.id.password);
connection = (TextView)findViewById(R.id.connection);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment())
.commit();
}
register.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View arg0) {
startActivity(new Intent(Login.this, Register.class));
}
});
login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new myTask().execute();
}
});
}
但每次点击登录按钮时我的连接都会创建。我希望我的应用程序在启动时连接到服务器,然后当我按下登录按钮时它会向服务器发送请求。如何更改我的代码?
感谢
答案 0 :(得分:1)
我认为最简单的方法是远离AsyncTasks并转移到Threads。在onCreate函数中创建一个新线程,创建套接字并连接它,然后让它等待来自UI线程的通知(最简单的方法是等待信号量或消息队列)。然后让按钮的onClick通知套接字线程它需要登录。使用此设计,您将在启动时连接它,但在您请求之前不能登录。
您最担心的是,如果您的服务器因无活动而超时连接。但我认为您可以控制服务器以防止这种情况发生。
答案 1 :(得分:1)
这里的问题是您正在使用doInBackground()
方法创建套接字。这意味着每次执行AsyncTask
的实例时,将重新创建该套接字。您可能想要做的是子类Application或某种单例并在那里初始化您的套接字。然后让你的AsyncTask
做类似的事情:
doInBackground(Object... params) {
// do stuff
Socket socket = Application.getSocket();
// do stuff with the socket
}
这引入了一些复杂性,因为您需要在应用程序生命周期的适当位置处理正确打开/关闭套接字,但这是最清晰的解决方案。