英文:
Android application not reading from Socket input stream
问题
我的安卓应用程序出现了问题,无法从服务器接收任何数据。奇怪的是,我编写的另一个套接字客户端(在我的计算机上运行,而不是在AVD上)可以接收并打印所有来自服务器的消息,没有任何问题。它使用了与doInBackground
方法中类似的代码。
public class Client extends AsyncTask<Void, Void, Void> {
int port;
Socket s;
@Override
protected Void doInBackground(Void... voids) {
try {
port = 1818;
s = new Socket("xx.xx.xx.xx", port);
if (!s.isConnected()) {
s.close();
}
BufferedReader re = new BufferedReader(new InputStreamReader(s.getInputStream()));
String temp = null;
while ((temp = re.readLine()) != null) {
MainActivity.changeT(temp); // This will replace the TextView's text with temp.
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
我在考虑一个可能的解决方案是将while循环放入单独的线程中,但我不太确定。欢迎任何建议!
英文:
My android application is not receiving any data from my server, for some reason. Strangely enough, a different socket client I wrote (which runs on my computer rather than an AVD) receives and prints all server-sent messages without fault. It uses similar code to what is held within the doInBackground
method.
public class Client extends AsyncTask<Void, Void, Void> {
int port;
Socket s;
@Override
protected Void doInBackground(Void... voids) {
try {
port = 1818;
s = new Socket("xx.xx.xx.xx", port);
if (!s.isConnected()) {
s.close();
}
BufferedReader re = new BufferedReader(new InputStreamReader(s.getInputStream()));
String temp = null;
while ((temp = re.readLine()) != null)
{
MainActivity.changeT(temp); // This will replace the TextView's text with temp.
}
}
catch(Exception e)
{
e.printStackTrace();
}
return null;
}
}
I am thinking a possible solution would be to place the while loop into a separate thread, but I am not sure. Any suggestions are welcome!
答案1
得分: 0
在应用程序正确访问服务器的同时,MainActivity.changeT(temp);
正试图从后台线程访问UI线程,这是不合适的。
我通过将MainActivity的实例传递给这个Client类来解决这个问题,并且我使用了runnable
方法 runOnUiThread(...)
。
public class Client extends AsyncTask<Void, Void, Void> {
int port;
Socket s;
MainActivity instance;
Client(MainActivity instance)
{
this.instance = instance;
}
@Override
protected Void doInBackground(Void... voids) {
try {
port = 1818;
s = new Socket("xx.xx.xx.xx", port);
if (!s.isConnected()) {
s.close();
return null;
}
BufferedReader re = new BufferedReader(new InputStreamReader(s.getInputStream()));
String temp = null;
TextView t = instance.getT(); // 访问返回TextView的getter方法。
while ((temp = re.readLine()) != null)
{
setText(t, temp); // 访问UI线程并更改TextView。
}
}
catch(Exception e)
{
e.printStackTrace();
}
return null;
}
private void setText(final TextView text,final String value){
instance.runOnUiThread(new Runnable() {
@Override
public void run() {
text.setText(value); // 这等同于在UI线程中编写代码。
}
});
}
}
英文:
While the application was accessing the server appropriately, MainActivity.changeT(temp);
is attempting to access the UI thread from a background thread, which is not appropriate.
I solved this by passing an instance of the MainActivity to this Client class, and I used the runnable
method runOnUiThread(...)
.
public class Client extends AsyncTask<Void, Void, Void> {
int port;
Socket s;
MainActivity instance;
Client(MainActivity instance)
{
this.instance = instance;
}
@Override
protected Void doInBackground(Void... voids) {
try {
port = 1818;
s = new Socket("xx.xx.xx.xx", port);
if (!s.isConnected()) {
s.close();
return null;
}
BufferedReader re = new BufferedReader(new InputStreamReader(s.getInputStream()));
String temp = null;
TextView t = instance.getT(); // Accesses a getter method that returns the TextView.
while ((temp = re.readLine()) != null)
{
setText(t, temp); // Accesses the UI Thread and changes the TextView.
}
}
catch(Exception e)
{
e.printStackTrace();
}
return null;
}
private void setText(final TextView text,final String value){
instance.runOnUiThread(new Runnable() {
@Override
public void run() {
text.setText(value); // This is equivalent to writing the code in the UI thread itself.
}
});
}
专注分享java语言的经验与见解,让所有开发者获益!
评论