1

I want to display a message when data from client is received. I started a server and a client. Client sends and receives confirmation from server, but on server side android, wasn't displayed any message, and app crashed, and here I paste what i got from log cat. and also inner class, when i want to show message:

import android.widget.Toast;

class Handler implements Runnable { 
    private Context myContext; 

    private static final String TAG = "myLogs";

    public Handler(Socket client) { 
        this.client = client; 
    } 
    public Handler(final Context context) { 
        this.myContext= context; 
    } 

    public void run() { 
        try {
            //message received..

            Toast.makeText(myContext.getApplicationContext(), "msg msg", Toast.LENGTH_SHORT).show();
            Log.d(TAG, "received....");
        } catch (IOException e) { 
            System.out.println("Errore: " + e); 
        } 
    } 
} 

Logcat

   04-29 17:21:53.679: D/My log(19533): waiting for connnections   
   04-29 17:24:13.726: D/My Log(19533): Connected     04-29
   17:24:14.859:W/dalvikvm(19533): threadid=9: thread exiting with uncaught exception    (group=0x40018578)     04-29 17:24:14.859: E/AndroidRuntime(19533): FATAL EXCEPTION: Thread-10 04-29
   17:24:14.859: E/AndroidRuntime(19533): java.lang.NullPointerException     04-29
   17:24:14.859:E/AndroidRuntime(19533): at com.example.tcpserver.Handler.run(Handler.java:49)     04-29
   17:24:14.859: E/AndroidRuntime(19533): at java.lang.Thread.run(Thread.java:1019)
2
  • your incomplete posted code doesn't make any sense... upload some more... Commented Apr 29, 2013 at 14:40
  • 1
    You cannot show Toast from outside the UI thread Commented Apr 29, 2013 at 14:45

6 Answers 6

3

There are two things wrong with your code. The first, as others have stated, is that you are calling the command from a non-ui thread. Although it is not evident from your code, the logcat suggests that you are calling this from a non-ui thread. In order to show a Toast message, you will need to ensure that you are calling the toast from within the UI thread.

The other issue is that you are attempting to show the Toast with the Application context. This will fail, because the application context cannot update the UI. Simply use the Activity context.

Your call for creating the Toast should be modified to look like this:

myContext.runOnUiThread(new Runnable() {
    @Override
    public void run() {
        Toast.makeText(myContext, "msg msg", Toast.LENGTH_SHORT).show();
    }
});
Sign up to request clarification or add additional context in comments.

10 Comments

this class implements Runnable (class Handler implements Runnable { ) and i am calling it inside run() , so i am in ui thread or not? i am confused.
@chajka, You need to place this block of code inside of your run() method. Your Handler class is running on a separate thread. run is overridden by all classes that implement Runnable or extend Thread, so you will see it a lot in development.
can i place it after public void run(){ try{ //send //receive//here
then it's asking to add cast to mycontext ((Object) myContext).runOnUiThread(new Runnable() {, do i need this?
@chajka, place it at run(){ try { //here }catch(Exception e){} }. As for the cast - you may need to cast it to an Activity (is new Handler(this) called from your Activity)?
|
0

After seeing more complete code, it is obvious that the design of this class has some major issues. The most obvious is that it has two constructors that take in different Objects, and ignore the other ones. Thus, there will either be a null socket, or a null context.

Second, as I posted in my other answer, there are some flaws with how the Toast is shown.

I propose you make some core changes to this class. For starts, remove your constructors and add this instead:

public Handler(Activity context, Socket client) { 
    this.client = client; 
    this.myContext= context; 
}

Now you can construct one instance and not worry about having null Objects. This also enforces you to construct this with Activity context - so you can call the method unOnUiThread, so now you can call:

((Activity) myContext).runOnUiThread(new Runnable() {
    @Override
    public void run() {
        Toast.makeText(myContext, "msg msg", Toast.LENGTH_SHORT).show();
    }
});

2 Comments

thx, a lot, but i got error again 04-29 20:42:34.640: E/AndroidRuntime(23347): FATAL EXCEPTION: Thread-10 04-29 20:42:34.640: E/AndroidRuntime(23347): java.lang.NullPointerException 04-29 20:42:34.640: E/AndroidRuntime(23347): at com.example.tcpserver.Handler.run(Handler.java:54) 04-29 20:42:34.640: E/AndroidRuntime(23347): at java.lang.Thread.run(Thread.java:1019) , it's this line ((Activity) myContext).runOnUiThread(new Runnable() {
@chajka, glad I could help. As for what the error is - you can debug a lot with print statements. Add this to your constructor: Log.d("Handler", "Context is " + context == null ? "null. Socket is " : "not null. Socket is " + socket == null ? "null." : "not null."; You can also try step-by-step debugging by adding a breakpoint to that line of code. More about debugging
0

You cannot show toast inside a thread that is not the main GUI thread.

It seems that you chose "Handler" as the name for the class you're writting. You should use a android.os.Handler to make this inside the GUI thread, not yours.

Also, it seems that you get a NullPointerException in your code. Can you tell us on which line it does occur ? (Edit : which line is "Handler.java:49" in your code)

6 Comments

yes, handler it's class i am writing it in(totally i have 3 classes, main, server, and handler), could u give some example, cause i don't understand what is GUI thread.. i am not sure i know in which line i got it, where can i check it?
It says Handler.java line 49.
Reading developer.android.com/guide/components/… and stackoverflow.com/questions/3652560/… should be very helpful (mandatory indeed)
line 49 :Toast.makeText(myContext.getApplicationContext(), "msg msg", Toast.LENGTH_SHORT).show();
Then split this line (1:text=makeText(...), 2:text.show()) then identify which one gives a NPE
|
0

You can only display toasts from the UI thread. Trying it from another thread will cause a crash. Have a look at Handlers, Handler.Callbacks and Messages.

HTH, Marc

Comments

0

I had the same problem. When I invoked the code on UI thread the issue resolved for me

public void showToastMessage(final String msg) {

    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            Toast.makeText(BaseActivity.this, msg, Toast.LENGTH_LONG).show();
        }

Comments

0

You can even do this without an Activity Context, like so:

new Handler(Looper.getMainLooper()).post( () -> 
    Toast.makeText(context, "Toast!", Toast.LENGTH_SHORT).show());

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.