2

I'm trying to get a bitmap drawn from a view, as I want to blur that bitmap and use it as a background for a following activity. Logcat gives me:

NullPointerException at android.graphics.Bitmap.createBitmap(Bitmap.java:484)

My code:

 @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // Get the view from activity_main.xml
    setContentView(R.layout.activity_splash_page);

    ProgressWheel wheel = (ProgressWheel) findViewById(R.id.progress_wheel);
    wheel.setClickable(false);

    TextView touch = (TextView) findViewById(R.id.touch_splash);
    touch.setClickable(false);

    TextView level = (TextView) findViewById(R.id.level_splash);
    level.setClickable(false);


    wheel.setProgress(0.7f);
    wheel.setClickable(true);
    touch.setClickable(true);
    level.setClickable(true);

    RelativeLayout view = (RelativeLayout)findViewById(R.id.viewtocapture);
    ImageView bmImage = (ImageView)findViewById(R.id.imageView);

    view.setDrawingCacheEnabled(true);
    // this is the important code :)
    // Without it the view will have a dimension of 0,0 and the bitmap will be null

    view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));

    view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());

    view.buildDrawingCache(true);
    view.buildDrawingCache();
    Bitmap b = Bitmap.createBitmap(view.getDrawingCache());      //Line 53
    view.setDrawingCacheEnabled(false); // clear drawing cache

    bmImage.setImageBitmap(b);


    wheel.setProgress(0.0f);

}

Here's the Stacktrace/Logcat:

Caused by: java.lang.NullPointerException
        at android.graphics.Bitmap.createBitmap(Bitmap.java:484)
        at com.redstonedevelopers.status_v1.SplashPage.onCreate(SplashPage.java:53)
        at android.app.Activity.performCreate(Activity.java:5047)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1094)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2056)       
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2117)
        at android.app.ActivityThread.access$700(ActivityThread.java:134)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1218)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:4867)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1007)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774)
        at dalvik.system.NativeStart.main(Native Method)

I've tried answers from: Here: take a screenshot from the activity Here: NullPointerException in createBitmap() from View and Here: android createBitmap NullPointerException

All to no avail. What should I change and/or do to get this working?

-R

12
  • 2
    at com.redstonedevelopers.status_v1.SplashPage.onCreate(SplashPage.java:53) show your onCreate and indicate line 53 please. Commented May 13, 2015 at 16:23
  • 1
    @redstonedev ok then put view.setDrawingCacheEnabled(true); exactly above view.buildDrawingCache(); Commented May 13, 2015 at 16:58
  • 1
    @redstonedev ok...one last solution I have: use view.getRootView().getDrawingCache() intsead of view.getDrawingCache() Commented May 13, 2015 at 17:02
  • 1
    You won't detect anything until its actually drawn for the first time. The view won't even be drawn on the screen in the On Create so its going to be null. You need to use TreeViewObserver and do all this then. Commented May 13, 2015 at 17:06
  • 1
    @redstonedev Try that answer out you can put it in your own method if you like. I use it when I need to know the size of a dynamic view the second that its drawn you can use it for other things though like what you're trying to do. Commented May 13, 2015 at 17:15

4 Answers 4

1

Try this.
This will kick off when your view is actually drawn.
Then you should be able to save the bitmap for it.

-----Make sure bmImage and view should be class level so we can use them when the ViewTreeObserver fires.

 bmImage = (ImageView)findViewById(R.id.imageView);
 view = (RelativeLayout)findViewById(R.id.viewtocapture);
 view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @SuppressWarnings("deprecation")
        @Override
        public void onGlobalLayout() {
            view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
            System.out.println(view == null ? "is null" : "not null");
            Bitmap b = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);                
            Canvas c = new Canvas(b);
            view.layout(view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
            view.draw(c);
            bmImage.setImageBitmap(b);
        }
    });
Sign up to request clarification or add additional context in comments.

17 Comments

@redstonedex make view a global variable. Go to your outer class and do RelativeLayout view; Then set it view = (RelativeLayout)findViewById(R.id.viewtocapture);
Editing the bitmap to the way I get a bitmap from a view
@restonedev keep in mind that bmImage also needs to be a global object. Because ViewTreeObserver doesn't fire off immediately and by the time it does trigger bmImage could be null.
You don't mean global, you mean class level. Global has a very well defined meaning - a global has scope, visibility and lifetime equal to the application.
@redstonedev hey dev implement my edit and see it view is null it shouldn't be
|
1

The view tree is not measured, laid out and rendered until after onCreate().

You can use a tree view layout observer, like this.

public void onCreate(Bundle savedInstanceState)
{
     super.onCreate(savedInstanceState);

     // inflate your main layout here (use RelativeLayout or whatever your root ViewGroup type is
     LinearLayout mainLayout = (LinearLayout ) this.getLayoutInflater().inflate(R.layout.activity_splash_page, null); 

     // set a global layout listener which will be called when the layout pass is completed and the view is drawn
     mainLayout.getViewTreeObserver().addOnGlobalLayoutListener(
     new ViewTreeObserver.OnGlobalLayoutListener() {
          public void onGlobalLayout() {
               //Remove the listener before proceeding
               if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                    mainLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
               } else {
                    mainLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
               }

               // do your thing here
          }
     }
 );

 setContentView(mainLayout);

Comments

1

I use code like this to draw a view onto a canvas object. Not sure if this will work in your case.

picturePreLoad = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
   Canvas canvas = new Canvas(picturePreLoad);
   MyView.draw(canvas);

Comments

0

In my case, the problem was that the bitmap files were copied by default in Drawable V24, instead of Drawable. To be able to see both folders at the same time, in the top left corner, change the setting from Android to Project.

Then go to app.src.main.res and there you can see both Drawable V24 and Drawable. You just have to remove the bitmaps from Drawable V24 and add them to Drawable.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.