简体   繁体   中英

Attempt to call a method but I get a NullPointerException

I want to create a connection through socket but I'm having trouble with the graphic of my App:

This is my activity:

public class Messaggi2 extends ActionBarActivity{

LinearLayout mLayout;
ScrollView scroll;
EditText scriviMessaggi;
Button invia; 
Socket connessione;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.messaggi2);

    mLayout = (LinearLayout) findViewById(R.id.LinearScrollLayout);
    scroll = (ScrollView) findViewById(R.id.scrollView2);
    scriviMessaggi = (EditText) findViewById(R.id.Scrivi);
    invia = (Button) findViewById(R.id.Invia);

    LavoraDietro asd = new LavoraDietro(connessione);
       asd.execute(); 
}


private TextView createNewTextView(String text) {
    final LinearLayout.LayoutParams lparams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);      final TextView textView = new TextView(this);
    textView.setLayoutParams(lparams);
    textView.setText(text);
    textView.setBackgroundResource(R.drawable.balloon_broadcast_incoming_pressed);
    return textView;
}


private TextView createNewTextViewSent(String text) {
    final LinearLayout.LayoutParams llparams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    llparams.gravity = Gravity.RIGHT;
    final TextView textViewSent = new TextView(this);
    textViewSent.setLayoutParams(llparams);
    textViewSent.setText(text);
    textViewSent.setBackgroundResource(R.drawable.balloon_outgoing_normal);
    return textViewSent;
}

public void AggiungiTextALlayout(String messaggio){
    mLayout.addView(createNewTextView(messaggio));  
    aggiornaScroll();
}
public void AggiungiTextInviatoALlayout(String messaggio){
    mLayout.addView(createNewTextViewSent(messaggio));  
    aggiornaScroll();
}

public void aggiornaScroll(){ 
    scroll.post(new Runnable() {
           @Override
           public void run() { 
             scroll.fullScroll(View.FOCUS_DOWN);
           }
        });
}
}

This is my AsynTask class:

public class LavoraDietro extends AsyncTask<Void, Void, Socket> {
Socket connessione;
boolean vediSeDeviPartire; 
Messaggi2 mess = new Messaggi2();

public LavoraDietro(Socket connessione){
    this.connessione = connessione;
}

@Override  
protected Socket doInBackground(Void... params){ 
    try {
        InetAddress local = InetAddress.getByName("192.168.1.71");
        connessione = new Socket(local , 7000); 

    } catch (UnknownHostException e) {
        e.printStackTrace();

    } catch (IOException e) {   
        e.printStackTrace();  
        return null;

    }catch(Exception e){
        e.printStackTrace();
        } 
    return connessione;
} 

@Override 
protected void onPostExecute(Socket result) {
    super.onPostExecute(result);
    if(result != null){ 
    vediSeDeviPartire = true;
    mess.AggiungiTextALlayout("Sono connesso al server");
    mess.AggiungiTextALlayout("I canali sono aperi..");
    }
    else{ 
    mess.AggiungiTextALlayout("ERRORE CONNESSIONE AL SERVER ");
    }
    }
} 

Using this code when I start my app the connection is established and then it crashes. What I see on my Logcat is this Exception:

java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference

So I tried to delete the content of my onPostExecute and everything works perfect. So the mistake is to try to call the method AggiungiTextAlLayout on my AsyncTask class. Can someone help me with this? Can someone suggest me something? I'm new in this field so I know that this is a stupid thing but I need help.

Thanks guys in advance

EDITED WITH THE SOLUTION

Thanks to Ataulm I got the problem and I solved it I changed the costructor of my LavoraDietro class (unfortunatly I can't change the name of variables and classes in English. But next time I ll use english Name of course )

LavoraDietro Class

public class LavoraDietro extends AsyncTask<Void, Void, Socket> {
Socket connessione;
boolean vediSeDeviPartire; 
Messaggi2 action;

public LavoraDietro(Socket connessione, Messaggi2 action){
    this.connessione = connessione;
    this.action = action;
}


@Override  
protected Socket doInBackground(Void... params){ 
    try {
        InetAddress local = InetAddress.getByName("192.168.1.71");
        connessione = new Socket(local , 7000); 

    } catch (UnknownHostException e) {
        e.printStackTrace();

    } catch (IOException e) {   
        e.printStackTrace();  
        return null;

    }catch(Exception e){
        e.printStackTrace();
        } 
    return connessione;
} 

@Override 
protected void onPostExecute(Socket result) {
    super.onPostExecute(result);
    if(result != null){ 
    vediSeDeviPartire = true;
    action.AggiungiTextALlayout("Sono connesso al server");
    action.AggiungiTextALlayout("I canali sono aperi..");
}
    else{ 
    action.AggiungiTextALlayout("ERRORE CONNESSIONE AL SERVER ");

    }
    }
} 

And in the Messaggi2 class I changed the call of the constructor in this:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.messaggi2);

    mLayout = (LinearLayout) findViewById(R.id.LinearScrollLayout);
    scroll = (ScrollView) findViewById(R.id.scrollView2);
    scriviMessaggi = (EditText) findViewById(R.id.Scrivi);
    invia = (Button) findViewById(R.id.Invia);


    LavoraDietro asd = new LavoraDietro(connessione, this);
       asd.execute(); 

Your AsyncTask has a reference to mess which is an object of type Messaggi2 .

Messaggi2 is a subclass of Activity . You attempt, inside your AsyncTask, to create a new instance of that class.

The Android system has no awareness of this object; it has called none of the life cycle methods, such as onCreate() where the activity's layout would typically be inflated. This means that none of your views are inflated nor even initialised.

When you call mess.AggiungiTextALlayout("Sono connesso al server"); , mLayout is null.

The NPE you see may likely not even be this one.

TL;DR: don't instantiate your Activity objects like Java objects; use them as specified within the Android framework.

I suspect you have this Activity starting correctly somewhere. The mistake is that you've not associated that activity with your Asynctask. When you create LavoraDietro , you pass a reference to the Socket in the constructor; you can also pass a reference to your activity, and assign that to the mess field, instead of calling new Messaggi2() . I'm not advocating this structure. But that is the issue at hand.

A few general tips to help you avoid this in future / or spot it faster:

  • be consistent with your naming; it's difficult to read your code when you're switching between English and Italian.
  • it's equally difficult for others to read your code if you don't maintain follow Java conventions with class/method names.
  • When you're extending Activity , it's typical to append the word "Activity" after your class; in this example new Messaggi2Activity() would have been easier to spot.
  • Where you're able, pass a Class's dependencies as parameters in the constructor; don't rely on constructing these dependencies yourself inside that class. Once you do this, you can begin to draw lines around what your class is responsible for; the less it's responsible for, the harder it is for your class to mess up.

那个问题是把没有“数据”的变量,验证您的变量

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM