1

I am getting this error,

"Attempt to invoke virtual method 'android.view.View android.view.View.getRootView()' on a null object reference"

Here is my code.

black.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            View bView = findViewById(R.id.lin);
            View root = bView.getRootView();
            root.setBackgroundColor(Color.parseColor("#000000"));
        }
    });

I have two views, one called overlay_view and the other activity_main. I am trying to change the color of overlay_view but I am getting this error. I have the setcontentView to activity_main, and if I switch it to overlay_view it does not give me a error. However I do not want to switch the setContentView to overlay_view so is there another way to do this? Thanks

Edit: I have a service which adds in overlay_view. The service is called from the mainactivity. Here is where it is called from in the main activity:

    public void sendMessage(){
    Intent intent = new Intent(this, DrawOverAppsService.class);

    startService(intent);
    Intent intent1 = new Intent(this, MainActivity.class);
}

And here is the service:

public class DrawOverAppsService extends Service {

public static final String TAG = "DrawOverAppsService";



View mOverlayView;

@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public void onCreate() {
    super.onCreate();

    Log.d(TAG, "onCreate");


    final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.MATCH_PARENT,
            WindowManager.LayoutParams.MATCH_PARENT,
            WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
                    WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
                    WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN |
                    WindowManager.LayoutParams.FLAG_DIM_BEHIND,
            PixelFormat.TRANSLUCENT);

    // An alpha value to apply to this entire window.
    // An alpha of 1.0 means fully opaque and 0.0 means fully transparent
    params.alpha = 0.1F;

    // When FLAG_DIM_BEHIND is set, this is the amount of dimming to apply.
    // Range is from 1.0 for completely opaque to 0.0 for no dim.
    params.dimAmount = 0.9F;

    WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);


    LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);


    mOverlayView = inflater.inflate(R.layout.overlay_view, null);

    wm.addView(mOverlayView, params);





}

@Override
public void onDestroy() {
    super.onDestroy();

    Log.d(TAG, "onDestroy");

        WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
        wm.removeView(mOverlayView);


}
}

This is the xml for overlay_view:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/lin"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#FF4081"
    android:orientation="vertical"></LinearLayout>
sandra burgle
  • 47
  • 1
  • 8

1 Answers1

1

Your issue is that you create a view in a service and want to reference it in the main activity to change its background color. Your line View bView = findViewById(R.id.lin) is giving you a null value because the system cannot find R.id.lin in activity_main. R.id.lin does exist in overlay_view and that is why you don't get the error with that view used in setContentView().

The service class variable mOverlayView has a reference to the view you want. I don't know of findViewById() functionality for views added via the window manager, so you will need to implement a connection between the activity and the service. The service code to change the background will look something like this:

View bView = mOverlayView.findViewById(R.id.lin);
if (bView != null) {}
    View root = bView.getRootView();
    root.setBackgroundColor(Color.parseColor("#000000"));
}

In the onClick handler of the activity, you will notify the service to change the background. There are several ways to handle this and you may already have a way to send commands to the service. If not, take a look at startService

Every call to this method will result in a corresponding call to the target service's onStartCommand(Intent, int, int) method, with the intent given here. This provides a convenient way to submit jobs to a service without having to bind and call on to its interface.

You can also set up a local broadcast manager or bind the service. Search for "android activity service communication" for results on alternate ways to handle this.

You may also want to familiarize yourself with this issue before proceeding.

Cheticamp
  • 61,413
  • 10
  • 78
  • 131
  • Thanks for the reply! lin is a linear layout in overlay_view, and overlay_view is the name of my second xml file. I am unsure if the view that is given as the argument to onClick is related, it was automatically put in when i was typing the code (I think you are talking about "View v"). I have a service which adds the overlay_view with special params to make it display transparent, and over top of all other things on screen. That is why I do not want to setContentView to overlay_view, because it loses its special params. I will edit my question with some more code since it is too long for here – sandra burgle Jun 26 '17 at 18:11
  • @sandraburgle Closer. What is `black` and where is the `OnClickListener` set? You need to get a reference to `mOverlayView` that is set in your service so your `findViewById()` works. Since the service maintains the class variable `mOverlayView`, you could just request the service set the background color from within `onClick()`. – Cheticamp Jun 26 '17 at 19:23
  • black is the id of the button. The OnClickListener is set in mainactivity. How would I set the background color in the service with onClick? By the way, thanks for taking the time and helping me so far I have been stuck on this for a long time. – sandra burgle Jun 27 '17 at 03:24
  • Thanks! I think this one will work. I am getting this error now : `06-27 15:58:29.803 1995-2861/? E/NetworkScheduler.SR: Invalid parameter app 06-27 15:58:29.804 1995-2861/? E/NetworkScheduler.SR: Invalid package name : Perhaps you didn't include a PendingIntent in the extras?` Do I need to use a pending intent? I am using `public void changeBlack(){ Intent intent = new Intent(this, ChangeColor.class); startService(intent); }` and I am calling `changeBlack` with `onClick`. I feel your answer will work so I will accept it, thanks! – sandra burgle Jun 27 '17 at 16:14
  • Oh, never mind, forget that comment above. I ran it again and `Unable to start service Intent U=0: not found` is the message. I found a solution here I think it will help me.[link](https://stackoverflow.com/questions/19105587/unable-to-start-service-intent-not-found) Thanks again, I upvoted and accepted your answer. – sandra burgle Jun 27 '17 at 16:37
  • @sandraburgle Your class name needs to be the class name of your service. Take another look at `startService()`. I think your answer is in the implementation of `onStartService()`. It is there that you should do your onClick processing. The intent will carry your instructions from the activity to the service. – Cheticamp Jun 27 '17 at 16:41
  • @sandraburgle [This](https://stackoverflow.com/a/15899750/6287910) might help you. – Cheticamp Jun 27 '17 at 16:47
  • Hey, I made a new post if you would like to check it out. I see what you meant with `onStartCommand`, it will really help me out down the road. Here is the new post, [link](https://stackoverflow.com/questions/44787114/color-of-view-wont-change-programmatically) – sandra burgle Jun 27 '17 at 18:13