2011-03-12 4 views
2

비 UI 스레드에서 일련의 webview 객체를 만들고 웹 뷰의 페이지로드가 완료되면 큐에 추가합니다. UI 쓰레드는 결국 웹뷰를 질의 할 것이고, 유지 된 큐에 요소가 있다면 그것은 큐에서 선택 될 것입니다. 이 비 UI 스레드는 영원히 계속 실행되며 필요시 큐를 &으로 채 웁니다. 불행하게도 UI 스레드가 웹 뷰를 렌더링 할 때 제대로 렌더링되지만 비 UI 스레드는 갑자기 'CalledFromWrongThreadException'오류로 실패합니다. 이 동작이 예상되는지 확실하지 않습니다. 같은 것을 보여주기위한 샘플 프로그램을 만들었습니다. 누군가 제가 여기서 문제를 식별하도록 도울 수 있습니까?비 ui 스레드에서 뷰 생성 및 UI 스레드에서 소모

public class MultiThreadTest extends Activity { 

    private volatile WebView mWv; 
    private LinearLayout mLL; 
    private volatile Handler nonUiThreadHandler = null; 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     mLL = (LinearLayout) findViewById(R.id.linearLayout); 
     Button creator = (Button) findViewById(R.id.creator); 
     creator.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View arg0) { 
       // TODO Auto-generated method stub 
       createThread(); 
      } 
     }); 

     Button consumer = (Button) findViewById(R.id.consumer); 
     consumer.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       // TODO Auto-generated method stub 
       mLL.addView(mWv, new LinearLayout.LayoutParams(200, 200)); 
       mWv.requestFocus(); 
      } 
     }); 
    } 

    public void createThread() { 

     Thread t = new Thread (new Runnable() {   
      @Override 
      public void run() { 
       Looper.prepare(); 
       nonUiThreadHandler = new Handler(); 
       Looper.loop();   
      } 
     }, "Creator thread"); 

     t.start(); 

     while (!t.isAlive() || nonUiThreadHandler==null) {} 

     nonUiThreadHandler.post(new Runnable() { 
      @Override 
      public void run() { 
       // TODO Auto-generated method stub 
       constructView(); 
      } 
     }); 
    } 

    public void constructView() { 
     mWv = new WebView(MultiThreadTest.this); 
     mWv.setWebChromeClient(new WebChromeClient()); 
     mWv.loadUrl("http://www.yahoo.com"); 
     mWv.setFocusable(true); 
    } 
} 

답변

2

이 예외가 발생했을 때를 기억하면 다른 스레드가 UI를 변경하려고 할 때 Android가 마음에 들지 않습니다. 당신이해야 할 일은 다른 스레드가 메인 UI 스레드 (Handler를 사용하여)에게 메시지를 다시 보내 변경 사항을 적용시키는 것입니다. 이것도 참조하십시오 : http://developer.android.com/guide/appendix/faq/commontasks.html#threading

+1

당신은 'runOnUiThread()'를 사용할 수도 있습니다. – bigstones

+0

예보기는 그들이 보여 질 스레드에 구성되어야합니다. – hackbod

+0

@anothem 지적 해 주셔서 고맙습니다. 예, 제한 사항을 알고 있습니다. 이것이 UI 스레드에서 다음 행을 수행하는 정확한 이유입니다. mLL.addView (mWv, new LinearLayout.LayoutParams (200, 200)); mWv.requestFocus(); (1/2) –

관련 문제