我在主类的顶部定义了connection
变量:
private XMPPConnection connection;
我使用以下代码连接到服务器:
public void connect(final String username,final String password) {
Thread t=new Thread(new Runnable() {
@Override
public void run() {
ConnectionConfiguration connConfig=new ConnectionConfiguration("server ip", 5222,"localhost");
XMPPConnection connection=new XMPPTCPConnection(connConfig);
try{
connection.connect();
}catch(XMPPException ex) {
setConnection(null);
} catch (SmackException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
connection.login(username,password);
} catch (SaslException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (XMPPException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SmackException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
setConnection(connection);
}
});
t.start();
}
您看到我正在使用线程进行此操作。如果连接成功setConnection
方法正在调用。
setConnection
方法:
public void setConnection(XMPPConnection connection) {
this.connection=connection;
if (connection != null) {
//Other stuff
....
所以,我在thread.Iut中设置connection
变量。但是当我想从服务器断开连接时,我正在收到崩溃报告。
断开代码:
try{
connection.disconnect();
}catch (SmackException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
报告:
01-27 14:14:05.162: E/XMPPConnection(3160): Error in listener while closing connection
01-27 14:14:05.162: E/XMPPConnection(3160): android.os.NetworkOnMainThreadException
01-27 14:14:05.162: E/XMPPConnection(3160): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1133)
01-27 14:14:05.162: E/XMPPConnection(3160): at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
01-27 14:14:05.162: E/XMPPConnection(3160): at java.net.InetAddress.getLocalHost(InetAddress.java:365)
01-27 14:14:05.162: E/XMPPConnection(3160): at org.jivesoftware.smackx.bytestreams.socks5.Socks5Proxy.<init>(Socks5Proxy.java:108)
我知道这个错误.Android不允许从ui thread使用网络操作。但是我已经在另一个线程中设置了连接。为什么我还需要一个线程来进行断开操作?
我遵循了本教程:http://developer.samsung.com/technical-doc/view.do?v=T000000119
在本教程中,他们没有使用另一个线程进行断开连接。为什么我收到此错误?
答案 0 :(得分:1)
使用您发布的代码。在活动或应用程序的onCreate方法中定义严格模式线程策略权限
假设您已在清单中提供了INTERNET权限
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy =
new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
如果您不想使用您已经发布的代码,我已经提到了以下替代解决方案
对网络相关操作或与长程序相关的
使用异步任务公共类MyActivity扩展了Activity {
XMPPConnection connection;
private String username;
private String password;
public void connect(final String username, final String password) {
ConnectionConfiguration connConfig = new ConnectionConfiguration(
"server ip", 5222, "localhost");
connection = new XMPPTCPConnection(connConfig);
try {
connection.connect();
} catch (XMPPException ex) {
setConnection(null);
} catch (SmackException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
connection.login(username, password);
} catch (SaslException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (XMPPException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SmackException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private class XMPPConnection extends AsyncTask<Void, Void, Void> {
/*
* (non-Javadoc)
*
* @see android.os.AsyncTask#doInBackground(Params[])
*/
@Override
protected Void doInBackground(Void... params) {
connect(username, password);
return null;
}
/*
* (non-Javadoc)
*
* @see android.os.AsyncTask#onPreExecute()
*/
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}
/*
* (non-Javadoc)
*
* @see android.os.AsyncTask#onPostExecute(java.lang.Object)
*/
@Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
// from here update the ui and make ui related changes once
// onpostExecute is called
setConnection(connection);
}
}
@Override
protected void onCreate(Bundle arg0) {
super.onCreate(arg0);
setContentView(R.layout.test_layout);
username = "username@chat.abc.com";
password = "1234567";
new XMPPConnection().execute();
}
}
另请检查this
对于异步和ui更改,主线程上的网络相关操作请检查this
并确保setConnection(XMPPConnection connection)
您没有做任何与UI更新相关的事情。
或者您也可以尝试
XMPPTCPConnection connection;
@Override
protected void onResume() {
super.onResume();
connect(LOGGED_USERNAME,"pass");
}
@Override
public void onPause() {
super.onPause();
try{
connection.disconnect();
}catch (SmackException e) {
e.printStackTrace();
}
}
private Handler handler = new Handler() {
/* (non-Javadoc)
* @see android.os.Handler#handleMessage(android.os.Message)
*/
@Override
public void handleMessage(Message msg) {
setConnection(connection);
}
};
public void connect(final String username, final String password) {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
ConnectionConfiguration connConfig = new ConnectionConfiguration(
"server ip", 5222, "localhost");
connection = new XMPPTCPConnection(connConfig);
try {
connection.connect();
} catch (XMPPException ex) {
setConnection(null);
} catch (SmackException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
connection.login(username, password);
} catch (SaslException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (XMPPException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SmackException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
handler.sendEmptyMessageAtTime(0, 1000);
}
});
t.start();
}
public void setConnection(XMPPTCPConnection connection) {
this.connection=connection;
if (connection != null) {
....