视图更改时,从AsyncTask访问视图失败

时间:2014-06-18 18:33:23

标签: android android-asynctask

我正在构建一个模块,以便在用户使用应用程序时捕获应用程序的屏幕截图(rootview)。我基本上是在尝试创建应用程序使用情况的视频录制。我决定从AsyncTask获取屏幕截图,因为我在截取屏幕截图时无法阻止主线程。这是我到目前为止的代码

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);
    Button record = (Button) findViewById(R.id.record);

    final View content = findViewById(R.id.record).getRootView();
    content.setDrawingCacheEnabled(true);       
    record.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            mtask = (CaptureSnap) new CaptureSnap(content,getApplicationContext()).execute();
        }
    });

}

AsyncTask中的代码来截取屏幕截图

private Bitmap getScreen(int index){
    View content = view.findViewById(R.id.record).getRootView();
    try{
    if(content != null){
        Log.i(TAG, "taking screenshot "+index);
        Bitmap bitmap = content.getDrawingCache();
        return bitmap;
    }else
        return null;
    }catch(NullPointerException e){
        Log.e(TAG, "Error for screenshot "+index);
        return null;
    }
}

@Override
protected String doInBackground(String... arg0) {
    while(indicator == 0){
        try{
            Bitmap screenshot = getScreen(0);
            Thread.sleep(100);
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

此代码工作正常,除非我尝试在截屏时使用该应用程序。我收到以下错误

    06-18 13:44:26.132: W/System.err(14096): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
06-18 13:44:26.164: W/System.err(14096):    at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4888)
06-18 13:44:26.164: W/System.err(14096):    at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:975)
06-18 13:44:26.164: W/System.err(14096):    at android.view.ViewGroup.invalidateChild(ViewGroup.java:4125)
06-18 13:44:26.171: W/System.err(14096):    at android.view.View.invalidate(View.java:10578)
06-18 13:44:26.171: W/System.err(14096):    at android.view.View.invalidate(View.java:10533)
06-18 13:44:26.171: W/System.err(14096):    at android.widget.AbsListView.draw(AbsListView.java:4261)
06-18 13:44:26.171: W/System.err(14096):    at android.view.View.draw(View.java:13710)
06-18 13:44:26.171: W/System.err(14096):    at android.view.ViewGroup.drawChild(ViewGroup.java:2988)
06-18 13:44:26.171: W/System.err(14096):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2858)
06-18 13:44:26.171: W/System.err(14096):    at android.view.View.draw(View.java:13708)
06-18 13:44:26.171: W/System.err(14096):    at android.view.ViewGroup.drawChild(ViewGroup.java:2988)
06-18 13:44:26.171: W/System.err(14096):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2858)
06-18 13:44:26.171: W/System.err(14096):    at android.view.View.draw(View.java:13829)
06-18 13:44:26.171: W/System.err(14096):    at android.widget.FrameLayout.draw(FrameLayout.java:467)
06-18 13:44:26.171: W/System.err(14096):    at android.view.View.draw(View.java:13710)
06-18 13:44:26.171: W/System.err(14096):    at android.view.ViewGroup.drawChild(ViewGroup.java:2988)
06-18 13:44:26.171: W/System.err(14096):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2858)
06-18 13:44:26.171: W/System.err(14096):    at android.view.View.draw(View.java:13708)
06-18 13:44:26.171: W/System.err(14096):    at android.view.ViewGroup.drawChild(ViewGroup.java:2988)
06-18 13:44:26.171: W/System.err(14096):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2858)
06-18 13:44:26.179: W/System.err(14096):    at android.view.View.draw(View.java:13829)
06-18 13:44:26.179: W/System.err(14096):    at android.widget.FrameLayout.draw(FrameLayout.java:467)
06-18 13:44:26.179: W/System.err(14096):    at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:2458)
06-18 13:44:26.187: W/System.err(14096):    at android.view.View.buildDrawingCache(View.java:13087)
06-18 13:44:26.187: W/System.err(14096):    at android.view.View.getDrawingCache(View.java:12875)
06-18 13:44:26.187: W/System.err(14096):    at android.view.View.getDrawingCache(View.java:12840)
06-18 13:44:26.187: W/System.err(14096):    at com.example.recordit.CaptureSnap.getScreen(CaptureSnap.java:158)

有人可以帮助我吗?

2 个答案:

答案 0 :(得分:0)

你需要从UI线程调用它,使用Handlerpost返回结果,以便UI线程可以在那里运行它

答案 1 :(得分:0)

当我用Handler替换AsyncTask时,我的问题就解决了。我在Acitivity中创建了一个CountDownTimer,它会将消息发布到处理程序,处理程序又会截取屏幕截图并将它们序列化为文件。稍后我使用这些文件将它们编码为使用JCodec的视频录制。谢谢你的帮助。