1

I have an interface implemented in MainActivity, and inside that callback method i want to update my TextView but i am getting nullpointer exception.

This is my MainActivity class

public class MainActivity extends AppCompatActivity implements GenericCallback
{

    Context mcontext;
    TextView tv;
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mcontext = this;

        Button btn = findViewById(R.id.btn);
        tv = findViewById(R.id.tv);
        btn.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                startActivity(new Intent(MainActivity.this,SecondActivity.class));
            }
        });

    }

    @Override
    public void doSomething(Context context, String... a)
    {
        Toast.makeText(context,"Calback"+a[0]+a[1],Toast.LENGTH_SHORT).show();
        tv = findViewById(R.id.tv);//Line 43
        tv.setText(a[0]+a[1]);
    }

My interface looks like this

public interface GenericCallback
{
    void doSomething(Context context, String... a);
}

My SecomdActivity

public class SecondActivity extends AppCompatActivity
{
    Context context;
    GenericCallback genericCallback = new MainActivity();

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        context = this;
        String a="Secomd",b = "Activity";
        genericCallback.doSomething(context,a,b);
        finish();
    }
}

StackTrace

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.Window$Callback android.view.Window.getCallback()' on a null object reference at android.support.v7.app.AppCompatDelegateImplBase.(AppCompatDelegateImplBase.java:117) at android.support.v7.app.AppCompatDelegateImplV9.(AppCompatDelegateImplV9.java:149) at android.support.v7.app.AppCompatDelegateImplV14.(AppCompatDelegateImplV14.java:56) at android.support.v7.app.AppCompatDelegateImplV23.(AppCompatDelegateImplV23.java:31) at android.support.v7.app.AppCompatDelegate.create(AppCompatDelegate.java:200) at android.support.v7.app.AppCompatDelegate.create(AppCompatDelegate.java:183) at android.support.v7.app.AppCompatActivity.getDelegate(AppCompatActivity.java:519) at android.support.v7.app.AppCompatActivity.findViewById(AppCompatActivity.java:190) at android.com.callback.MainActivity.doSomething(MainActivity.java:43) at android.com.callback.SecondActivity.onCreate(SecondActivity.java:21)

I already know what is nullpointer, I already referred this and this

Akshay Katariya
  • 338
  • 4
  • 16

3 Answers3

1

You can use EventBus Library

For installation

compile 'org.greenrobot:eventbus:3.1.1'

First, create a Java class

public class MsgEvent {
String oo;

public String getOo() {
    return oo;
}

public void setOo(String oo) {
    this.oo = oo;
}
}

Then in SecondActivity

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_second);
    context = this;
    String a="Secomd",b = "Activity";
    MsgEvent msgEvent = new MsgEvnet();
    msgEvent.setOo(a);
    EventBus.getDefault().post(msgEvent);
    finish();
}

Then in MainActivity

@Override
public void onStart() {
 super.onStart();
 EventBus.getDefault().register(this);
}

@Override
public void onStop() {
 super.onStop();
 EventBus.getDefault().unregister(this);
}
@Subscribe(threadMode = ThreadMode.MAIN)  
public void onMessageEvent(MsgEvent event) {
String value = event.getOo();
}
theanilpaudel
  • 3,348
  • 8
  • 39
  • 67
1

You can use BroadcastReceiver

check the below example

MainActivity

public class MainActivity extends AppCompatActivity {


    TextView mTitle;


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

        mTitle = findViewById(R.id.toolbar_title);

        startActivity(new Intent(this, SecondActivity.class));

    }

    private BroadcastReceiver myBroadcastReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            mTitle.setText(intent.getStringExtra("DATA"));
            Toast.makeText(context, "recieved text : " + intent.getStringExtra("DATA"), Toast.LENGTH_SHORT).show();

        }
    };

    @Override
    protected void onResume() {
        IntentFilter filter = new IntentFilter();
        filter.addAction("MY_ACTION");
        registerReceiver(myBroadcastReceiver, filter);

        super.onResume();
    }

    @Override
    protected void onPause() {

        super.onPause();
    }

}

XML form MainActivity

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/toolbarIcon"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:orientation="vertical">


    <TextView
        android:id="@+id/toolbar_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="50dp"
        android:text="Nilesh"
        android:textStyle="bold" />


</LinearLayout>

Second_activity

    public class SecondActivity extends AppCompatActivity {

    TextView tvText;

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

        getSupportActionBar().setTitle("SECOND Activity");


        tvText = findViewById(R.id.tvText);

        tvText.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                sendBroadcast();
            }
        });

    }

    public void sendBroadcast() {

        Intent broadcast = new Intent();
        broadcast.putExtra("DATA", "MY NAME IS NILESH");
        broadcast.setAction("MY_ACTION");
        sendBroadcast(broadcast);
    }
}

LAYOUT for second activity

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".SecondActivity">

    <TextView
        android:layout_width="match_parent"
        android:id="@+id/tvText"
        android:text="Click to Send Broadcas"
        android:layout_height="wrap_content" />

</LinearLayout>
AskNilesh
  • 67,701
  • 16
  • 123
  • 163
  • my second activity over here is just an example in my actual code its a broadcastReceiver and i want to get a callback from that broadCastReceiver so i dont think this is good idea to invoke a new broadcast from broadcast – Akshay Katariya Apr 27 '18 at 10:17
  • *`i dont think this is good idea to invoke a new broadcast from broadcast`* why @AkshayKatariya – AskNilesh Apr 27 '18 at 10:22
  • I know this can be done by broadcast as well, Implementation wise callback is much more simple and for my use case i dont think i should call another broadcast by the ways +1 for you answer and efforts – Akshay Katariya Apr 27 '18 at 10:26
0

The reason you are getting that null exception is that your MainActivity view is not inflated because it is not instantiated by the framework.

You can create an instance getter method from your first activity.

private static GenericCallback instance;

public static GenericCallback getHandler() {
    return instance;
}

@Override
protected void onCreate(Bundle savedInstanceState)
{
     ...
     instance = this;
     ...
}

And then on your 2nd activity, get that instance instead of instantiating an activity.

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_second);
    context = this;
    String a="Secomd",b = "Activity";
    GenericCallback genericCallback = MainActivity.getHandler();
    genericCallback.doSomething(context,a,b);
    finish();
}
tompee
  • 1,408
  • 1
  • 7
  • 6
  • 1
    You do realize that your genericCallback is a new instance of MainActivity? You do not instantiate an activity. You let the framework do that for you. – tompee Apr 27 '18 at 09:40
  • so what im suppose to do? i want to update my ui from this callback – Akshay Katariya Apr 27 '18 at 09:42
  • return this //cannot be refered to static context Besides where will get my data in getHandler() method or the callback's method? – Akshay Katariya Apr 27 '18 at 10:00
  • @AkshayKatariya check my below ans with **`BroadcastReceiver`** – AskNilesh Apr 27 '18 at 10:03
  • i updated my answer to fix that static context. The main idea is, you have to pass your GenericCallback instance to the 2nd activity. – tompee Apr 27 '18 at 10:06
  • your code worked :-) can you tell me what was wrong in my code. Will test it with my actual code and accept your answer – Akshay Katariya Apr 27 '18 at 10:20
  • As I was saying some 45 mins ago, you instantiated a new MainActivity. What you should be doing is to take the instance of your MainActivity that was instantiated by the framework and pass it to your next activity. However, there is not a straightforward way of passing object across activities. You can use an eventbus if you want. But since you are bent on using your own implementation, I just exposed your MainActivity as a static object and requested it from your 2nd activity. – tompee Apr 27 '18 at 10:26