Mohamed Gamal
Mohamed Gamal

Reputation: 1348

Android Button inside running thread crash

Thanks i got it to Work by using Toggled Value at the button

public void onClick(View v) {
                               // TODO Auto-generated method stub

                             doit=1;
                             Log.e("ErrorButton","NextTime "+doit);
                           }
                       });  
                      if(doit==1)
                      {
                          Log.e("ErrorButton","If");
                      ////
                          out = new PrintWriter( new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())),true); 
                        in = new BufferedReader(new InputStreamReader(socket.getInputStream()));                

                        out.println("Helloo");

                        while ((text = in.readLine()) != null) {
                            finall += text;
                            Log.e("Test","Final: "+finall);
                          if(text=="quit")
                          {
                              socket.close();
                          }
                      Log.e("ClientActivity", "After Read "+doit+" "+finall);
                     // in.close();

                       doit=0;
                       Log.e("ClientActivity", "After If "+doit);
                      } 

Whenever i click on the button the code performs its task then crashes

Heres my android Code:

package com.example.socketclient;


import android.R.string;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
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;

import java.io.BufferedReader;
import java.io.BufferedWriter; 
import java.io.IOException; 
import java.io.InputStream;
import java.io.OutputStreamWriter; 
import java.io.InputStreamReader;
import java.io.PrintWriter; 
import java.net.InetAddress; 
import java.net.Socket; 
import java.net.UnknownHostException; 
import android.util.Log; 

public class SocketCode extends Activity {
    private boolean connected = false;
    //private Handler handler = new Handler();
    public TextView txt;
    protected SocketCore Conn;
    public Button b;
    public EditText TextToSend;
    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_socket_code);
        b = (Button)findViewById(R.id.button1);
        txt = (TextView)findViewById(R.id.textView1);
        TextToSend = (EditText)findViewById(R.id.editText1);
        //Conn = new SocketCore(this,txt);

        Thread cThread = new Thread(new ClientThread());
        cThread.start();

    }
    public class ClientThread implements Runnable {
        Socket socket ;
String finall;
        public void run() {
            try {
                InetAddress serverAddr = InetAddress.getByName("192.168.0.150");
                Log.d("ClientActivity", "C: Connecting...");
                socket= new Socket(serverAddr,4444);
                connected = true;
                while (connected) {
                    try {
                        Log.d("ClientActivity", "C: Sending command.");

                       b.setOnClickListener(new View.OnClickListener() {

                           public void onClick(View v) {
                               // TODO Auto-generated method stub

                               ClientHandler("Hex");

                           }
                       });  




                            Log.d("ClientActivity", "C: Sent.");


                    } catch (Exception e) {
                        Log.e("ClientActivity", "S: Error", e);
                    }
                    Thread.sleep(2000);
                }
                socket.close();
                txt.setText("Closed Socket");
                Log.d("ClientActivity", "C: Closed.");
            } catch (Exception e) {
                Log.e("ClientActivity", "C: Error", e);
                connected = false;
            }
        }

        public void ClientHandler(String Send)
        {
            try{
              PrintWriter   out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket
                       .getOutputStream())), true);
          out.println(Send);
           BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
           finall = in.readLine();

           txt.setText(finall);
            }
            catch(IOException e)
            {txt.setText("Exception");}
        }


    }

}

Here is the Error Log:

11-24 23:44:12.920: E/AndroidRuntime(10046): FATAL EXCEPTION: main
11-24 23:44:12.920: E/AndroidRuntime(10046): android.os.NetworkOnMainThreadException
11-24 23:44:12.920: E/AndroidRuntime(10046):    at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1118)
11-24 23:44:12.920: E/AndroidRuntime(10046):    at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:163)
11-24 23:44:12.920: E/AndroidRuntime(10046):    at libcore.io.IoBridge.recvfrom(IoBridge.java:513)
11-24 23:44:12.920: E/AndroidRuntime(10046):    at java.net.PlainSocketImpl.read(PlainSocketImpl.java:488)
11-24 23:44:12.920: E/AndroidRuntime(10046):    at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:46)
11-24 23:44:12.920: E/AndroidRuntime(10046):    at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:240)
11-24 23:44:12.920: E/AndroidRuntime(10046):    at java.io.InputStreamReader.read(InputStreamReader.java:244)
11-24 23:44:12.920: E/AndroidRuntime(10046):    at java.io.BufferedReader.fillBuf(BufferedReader.java:130)
11-24 23:44:12.920: E/AndroidRuntime(10046):    at java.io.BufferedReader.readLine(BufferedReader.java:354)
11-24 23:44:12.920: E/AndroidRuntime(10046):    at com.example.socketclient.SocketCode$ClientThread.ClientHandler(SocketCode.java:103)
11-24 23:44:12.920: E/AndroidRuntime(10046):    at com.example.socketclient.SocketCode$ClientThread$1.onClick(SocketCode.java:66)
11-24 23:44:12.920: E/AndroidRuntime(10046):    at android.view.View.performClick(View.java:4211)
11-24 23:44:12.920: E/AndroidRuntime(10046):    at android.view.View$PerformClick.run(View.java:17267)
11-24 23:44:12.920: E/AndroidRuntime(10046):    at android.os.Handler.handleCallback(Handler.java:615)
11-24 23:44:12.920: E/AndroidRuntime(10046):    at android.os.Handler.dispatchMessage(Handler.java:92)
11-24 23:44:12.920: E/AndroidRuntime(10046):    at android.os.Looper.loop(Looper.java:137)
11-24 23:44:12.920: E/AndroidRuntime(10046):    at android.app.ActivityThread.main(ActivityThread.java:4898)
11-24 23:44:12.920: E/AndroidRuntime(10046):    at java.lang.reflect.Method.invokeNative(Native Method)
11-24 23:44:12.920: E/AndroidRuntime(10046):    at java.lang.reflect.Method.invoke(Method.java:511)
11-24 23:44:12.920: E/AndroidRuntime(10046):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006)
11-24 23:44:12.920: E/AndroidRuntime(10046):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
11-24 23:44:12.920: E/AndroidRuntime(10046):    at dalvik.system.NativeStart.main(Native Method)

Note: The server side accepts connection without a problem also accepts data from client before it crashes

Upvotes: 0

Views: 1272

Answers (4)

Jatin
Jatin

Reputation: 31744

According to this. The exception that is thrown when an application attempts to perform a networking operation on its main thread.

The issue is this line

PrintWriter   out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket
                   .getOutputStream())), true);

When you do b.setOnClickListener your View.OnClickListener() and hence ClientHandler is executed by the UI thread and not the generated thead. Later UI thread tries to perform the above operation which contains socket.getOutputStream() and hence the exception

This is primarily done because, Android tool kit like many others is not thread safe. UI Thread performs all the UI operations. Networking operation normally have latency associated with them. if the Ui thread is busy doing networks, how can it render anything on screen?

Upvotes: 1

Artyom Kiriliyk
Artyom Kiriliyk

Reputation: 2513

Change this part and add runOnUiThread:

runOnUiThread(new Runnable() 
{
    public void run() 
    {
        b.setOnClickListener(new View.OnClickListener() {...});
        // and also Logs
    }
});

Upvotes: 1

Strict mode is developer tool for detecting certain operations in UI thread. Read this for the details http://developer.android.com/reference/android/os/StrictMode.html

Strict mode is enabled by default starting from Android version 3.0.

Upvotes: 0

Praful Bhatnagar
Praful Bhatnagar

Reputation: 7435

Check this out http://developer.android.com/reference/android/os/NetworkOnMainThreadException.html. As per official doc if you are using Honeycomb SDK or above your should not put network operation on the main/UI thread. Applications targeting earlier SDK versions are allowed to do networking on their main event loop threads, but it's heavily discouraged since it would block the UI and can cause ANR.

You need to use an background thread or AsyncTask for network operation to avoid getting this exception.

As a general rule always put time consuming task in background thread or AsyncTask.

Upvotes: 0

Related Questions