get screenshot for a ScrollView in worker thread

I need to get screenshot for a ScrollView. My code is as bellow:

private File getScreenShot() {
    final int count = mScrollView.getChildCount();
    int height = 0;
    for (int i = 0; i < count; i++) {
        View view = mScrollView.getChildAt(i);
        height += view.getHeight();
    }

    // get screen shot bitmap
    Bitmap bitmap = Bitmap.createBitmap(mScrollView.getWidth(), height,
            Bitmap.Config.RGB_565);
    final Canvas canvas = new Canvas(bitmap);
    mScrollView.draw(canvas);

    // save to a temp file
    return saveToFile(bitmap);
}

Because my mScrollView is so long that some of content will be hidden until user scrolls down, it spends much time capturing the screenshot(nearly 100ms) and temporarily stops the UI thread. So I decide to run the method in another thread. Code likes:

new Thread() {
    @Override
    public void run() {
        System.out.println(Thread.currentThread());
        mShareFile = getScreenShot();
        mHandler.sendEmptyMessage(96);
    }
}.start();

But something interesting came: I tried to use a subclass of Thread and AsyncTask. Each of them can do the job in most time. However, in a few times an exception will be thrown and cause app crash:

android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

But how can I run the code successfully in most time? I mean, if I can get this exception, indeed I did something wrong(call View.draw(Canvas) outside main thread). The failure won't happen for the first or second time running the code while it can happen for the third time. And I tried to scroll the ScrollView and call the method before scrolling stops, it may cause the crash. But if I do the same thing for the first time, crash won't happen, either.

I output the thread, it belongs to main group -> [Thread XXXXX, 5, main]

I don't know why this strange result happened? Can someone tell me the reason? How can I get screenshot of a ScrollView in another thread?

Answers


I wouldnt try to take a screenshot from another thread. I would take the screenshot from the main thread and save it to disk on another thread.

Have you tried the drawing cache?

mScrollView.setDrawingCacheEnabled(true);
Bitmap bitmap = Bitmap.createBitmap(mScrollView.getDrawingCache());
mScrollView.setDrawingCacheEnabled(false);

If it does not improve performance, I would take a screenshot of the children of mScrollView and assemble them into one bitmap on another thread. It would allow you to yield the UI thread between children.


Need Your Help

Changing the Array Prototype in JavaScript

javascript arrays javascript-objects

I'm trying to change the Array Prototype and access columns as if they are rows therefor doing a custom matrix transposition. I want to make sure that the access of each column doesn't require re-

Rubymine 8: How to turn off Database Detector

rubymine rubymine-7

How do I turn off the Database Detector in RubyMine 8?