Построение представлений в потоке не-пользовательского интерфейса и использование в потоке пользовательского интерфейса - PullRequest
3 голосов
/ 12 марта 2011

Я создаю набор объектов веб-просмотра в потоке, не являющемся пользовательским интерфейсом, и продолжаю добавлять их в очередь после завершения загрузки страницы веб-просмотра. Поток пользовательского интерфейса в конечном итоге запросит веб-просмотр, и если в поддерживаемой очереди есть элементы, он будет выбран из очереди. Этот поток, не связанный с пользовательским интерфейсом, будет работать вечно и заполнять очередь по мере необходимости. К сожалению, когда поток пользовательского интерфейса отображает веб-просмотр, хотя он отображается правильно, поток, не являющийся пользовательским интерфейсом, неожиданно завершается с ошибкой CalledFromWrongThreadException. Я не уверен, ожидается ли такое поведение. Я создал пример программы, чтобы продемонстрировать то же самое. Может ли кто-нибудь помочь мне определить проблему здесь?

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);
    }
} 

1 Ответ

2 голосов
/ 12 марта 2011

Если я правильно помню, когда я столкнулся с этим исключением, Android не нравится, когда другой поток пытается внести изменения в пользовательский интерфейс. Вам нужно, чтобы другие потоки отправили какое-то сообщение обратно в основной поток пользовательского интерфейса (с помощью обработчика) для выполнения этих изменений. Смотрите также: http://developer.android.com/guide/appendix/faq/commontasks.html#threading

...