通过回调从线程到达Gui

时间:2014-05-17 15:03:16

标签: android multithreading

我试图通过回调访问主线程。但是当我尝试运行它时,我得到一个例外。我做错了什么,但我不知道是什么。

 05-17 16:16:21.315    6799-6834/be.appmax.ktsjjt E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-293
    Process: be.appmax.ktsjjt, PID: 6799
    android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
            at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6094)
            at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:857)
            at android.view.ViewGroup.invalidateChild(ViewGroup.java:4320)
            at android.view.View.invalidate(View.java:10942)
            at android.view.View.invalidate(View.java:10897)
            at android.widget.TextView.checkForRelayout(TextView.java:6587)
            at android.widget.TextView.setText(TextView.java:3813)
            at android.widget.TextView.setText(TextView.java:3671)
            at android.widget.TextView.setText(TextView.java:3646)
            at be.appmax.ktsjjt.LoginActivity.onGsonSyncObjectCompleted(LoginActivity.java:186)
            at be.appmax.ktsjjt.handlers.SyncHandlers.SyncHandler.onGsonTaskCompleted(SyncHandler.java:50)
            at be.appmax.ktsjjt.handlers.SyncHandlers.GsonHandler.run(GsonHandler.java:159)
            at java.lang.Thread.run(Thread.java:841)

这是我用来从线程进行回调的代码:

public class DatabaseHandler implements Runnable {

private static DatabaseHandler databaseHandler;
private OnDatabaseTaskCompleted listener;

private LinkedBlockingQueue<Pair<Integer, List<? extends DatabaseModel>>> queue = new LinkedBlockingQueue<Pair<Integer, List<? extends DatabaseModel>>>();
private Boolean run = true;

public DatabaseHandler(OnDatabaseTaskCompleted databaseTask) {
    listener = databaseTask;
}

public static DatabaseHandler getInstance(OnDatabaseTaskCompleted databaseTask) {
    if (databaseHandler == null) {
        try {
            databaseHandler = new DatabaseHandler(databaseTask);

            new Thread(databaseHandler).start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    return databaseHandler;
}

@Override
public void run() {
    while (run) {
        synchronized (queue) {
            while (queue.isEmpty()) {
                try {
                    queue.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        }
        Pair<Integer, List<? extends DatabaseModel>> pair = queue.poll();
        Tools.LOG_DEBUG("New pair: database");
        if (pair.second.size() > 0) {
            pair.second.get(0).SaveAll(Shared.dbRepo, pair.second);
        }
        listener.onDatabaseTaskCompleted(pair.first);
    }
}

public void add(int function, List<? extends DatabaseModel> models) {
    try {
        synchronized (queue) {
            queue.put(new Pair(function, models));
            queue.notify();
        }
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}
}

我在GUI上执行操作的回调:

@Override
public void onGsonSyncObjectCompleted(int function, DatabaseModel model) {
    switch (function) {
        case Constants.FUNCTION_GSON_MY_PROFILE:
            Shared.myProfile = (Profile) model;
            Tools.LOG_DEBUG(Shared.myProfile.toString());

            if (Shared.myProfile != null) {
                loginButton.setEnabled(false);

                loadingText.setText(getResources().getString(R.string.login_loading) + " data");
                onWaitHandler();
            }
            break;
    }
}

1 个答案:

答案 0 :(得分:1)

您无法从不是UI线程的线程执行更改UI控件的代码。您可以使用post

loginButton.post(new Runnable() { 
   /* code to execute in UI thread */ 
   @Override public void run() { 

   }
});

runnable将在UI线程中执行。

Handler