我是android和socket编程的新手。我正在开发一个客户端向服务器发送字符串的项目。当服务器获取String时,将更改TextView的文本。 问题是每当客户端发送字符串时,服务器就会崩溃(当我使用setText()函数时)。 这是我的代码:
public class Download extends AppCompatActivity {
GetRequestedURLAsyncTask __getRequestedURLAsyncTask;
TextView incomingURL;
Button downloadButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_download);
incomingURL = (TextView) this.findViewById(R.id.incomingURL);
downloadButton = (Button) this.findViewById(R.id.disconnectButton);
__getRequestedURLAsyncTask = new GetRequestedURLAsyncTask(this);
__getRequestedURLAsyncTask.execute(this);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_download, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private class GetRequestedURLAsyncTask extends AsyncTask {
private Context context;
private TextView statusText;
private String requestedURL;
public GetRequestedURLAsyncTask(Context context) {
this.context = context;
}
@Override
protected Object doInBackground(Object[] params) {
ServerSocket serverSocket = null;
Socket client = null;
try {
Log.v("transferService", "Creating server socket");
serverSocket = new ServerSocket(8282);
Log.v("transferService", "Creating client socket");
client = serverSocket.accept();
InetAddress inetAddress = client.getInetAddress();
Log.d("New connection made from ", inetAddress.getHostAddress());
Log.d("IncomingText", "Init input");
DataInputStream input = new DataInputStream(client.getInputStream());
while(true)
{
try
{
requestedURL = input.readLine().toString();
Log.d("incomingText", requestedURL);
setRequestedUrl(requestedURL);
}
catch (IOException e)
{
}
}
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
protected void onPostExecute(String result)
{
if (result != null)
{
setRequestedUrl(result);
}
}
public String getRequestedUrl()
{
return this.requestedURL;
}
}
private void setRequestedUrl(String s)
{
this.incomingURL.setText(s);
}
}
和logcat:
FATAL EXCEPTION: AsyncTask #1
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:299)
at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)
Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4876)
at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:948)
at android.view.View.requestLayout(View.java:15245)
at android.view.View.requestLayout(View.java:15245)
at android.view.View.requestLayout(View.java:15245)
at android.view.View.requestLayout(View.java:15245)
at android.view.View.requestLayout(View.java:15245)
at android.view.View.requestLayout(View.java:15245)
at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:292)
at android.view.View.requestLayout(View.java:15245)
at android.widget.TextView.checkForRelayout(TextView.java:6632)
at android.widget.TextView.setText(TextView.java:3736)
at android.widget.TextView.setText(TextView.java:3594)
at android.widget.TextView.setText(TextView.java:3569)
at Download.setRequestedUrl(Download.java:147)
at Download.access$000(Download.java:24)
at Download$GetRequestedURLAsyncTask.doInBackground(Download.java:109)
at android.os.AsyncTask$2.call(AsyncTask.java:287)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
任何建议都会有所帮助。
答案 0 :(得分:2)
删除setRequestedUrl(requestedURL)
方法中对doInBackground
的来电。 doInBackground
方法发生在主线程之外。您只能使用onPreExecute
onPostExecute
,onProgressUpdate
或AsyncTask
方法修改视图