为什么主线程无法更新horizo​​ntallistview中的UI元素?

时间:2013-06-17 23:58:47

标签: android multithreading listview android-asynctask

最近几天,我正在尝试更新自定义HorizontalListView中的部分UI视图。我一直在尝试无数的方式,如使用异步任务,通过处理程序等发布消息。我没有想出更新它们。结果,我尝试构建一个队列系统来逐个更新它们。这是我的代码,它仍然没有更新它们。

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Queue;

import roboguice.RoboGuice;
import CustomChannel;
import EGPInfo;
import android.content.Context;
import android.os.Handler;
import android.util.Log;
import android.widget.TextView;

public class EPGLoader {

    static private EPGLoader _instance;

    public static EPGLoader getInstance(Context context) {
        if (_instance == null) {
            _instance = new EPGLoader();
        }
        mContext = context;
        return _instance;
    }

    private HashMap<String, WeakReference<EPGChannel>> _cachedChannels;
    private Queue<EPGChannel> _queue;
    private EPGThread _thread;
    private static Context mContext;
    private boolean _isBusy;

    public EPGLoader() {
        _cachedChannels = new HashMap<String, WeakReference<EPGChannel>>();
        _queue = new LinkedList<EPGChannel>();
        _isBusy = false;
    }

    public void load(ArrayList<TextView> textViews, CustomChannel channel) {
        Iterator<EPGChannel> it = _queue.iterator();

        EPGChannel epgChannel = new EPGChannel();
        epgChannel.setChannel(channel);
        epgChannel.setTextViews(textViews);

        while (it.hasNext()) {
            if (it.next().equals(epgChannel)) {
                it.remove();
                break;
            }
        }

        _queue.add(epgChannel);
        loadNext();
    }

    private void loadNext() {
        Iterator<EPGChannel> it = _queue.iterator();
        if (!_isBusy && it.hasNext()) {
            _isBusy = true;
            EPGChannel epgChannel = it.next();
            it.remove();
            EPGChannel epgCache = get(epgChannel.getChannel().getChannelId());
            if (epgCache != null) {
                Log.i("A", "Cache");
                epgChannel.textViews.get(0).setText("1");
                epgChannel.textViews.get(1).setText("2");
                epgChannel.textViews.get(2).setText("3");
                epgChannel.textViews.get(3).setText("4");
                _isBusy = false;
                loadNext();
            } else {
                _thread = new EPGThread(epgChannel);
                _thread.start();
                Log.i("A", "Live");
            }
        }
    }

    private EPGChannel get(String channelId) {
        if (_cachedChannels.containsKey(channelId)) {
            return _cachedChannels.get(channelId).get();
        } else {
            return null;
        }
    }

    private class EPGThread extends Thread {

        private EPGChannel EPGChannel;

        final Handler threadHandler = new Handler();
        final Runnable threadCallBack = new Runnable() {

            @Override
            public void run() {
                onLoad();
            }
        };

        public EPGThread(EPGChannel epgChannel) {
            this.EPGChannel = epgChannel;
        }

        private void onLoad() {
            if (_thread != null) {
                EPGChannel epgChannel = _thread.EPGChannel;
//              epgChannel.getTextViews().get(1).setText(epgChannel.getChannel().getName());
                epgChannel.getTextViews().get(0).setText("1");
                epgChannel.getTextViews().get(1).setText("2");
                epgChannel.getTextViews().get(2).setText("3");
                epgChannel.getTextViews().get(3).setText("4");
            }
            _thread = null;
            _isBusy = false;
            loadNext();
        }

        @Override
        public void run() {
            try {
                _isBusy = true;
                ChannelManager channelManager = RoboGuice.getInjector(mContext).getInstance(ChannelManager.class);
                ArrayList<EGPInfo> epgInfo = channelManager.getChannelEPG(EPGChannel.getChannel().getChannelId());
                if (epgInfo.size() == 2) {
                    EPGChannel.getChannel().updateEPGInformations(epgInfo.get(0), epgInfo.get(1));
                }
                if (!_cachedChannels.containsKey(EPGChannel.getChannel().getChannelId()))
                    _cachedChannels.put(EPGChannel.getChannel().getChannelId(), new WeakReference<EPGLoader.EPGChannel>(EPGChannel));
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                threadHandler.post(threadCallBack);
            }
        }

    }

    private class EPGChannel {

        private ArrayList<TextView> textViews;
        private CustomChannel channel;

        public ArrayList<TextView> getTextViews() {
            return textViews;
        }

        public void setTextViews(ArrayList<TextView> textViews) {
            this.textViews = textViews;
        }

        public CustomChannel getChannel() {
            return channel;
        }

        public void setChannel(CustomChannel channel) {
            this.channel = channel;
        }

    }

}

当ArrayAdapter的getView事件触发时,我从主线程调用它。

@Override
public View getView(int position, View retval, ViewGroup parent) {

if (retval == null) {
    retval = LayoutInflater.from(parent.getContext()).inflate(R.layout.channel_item, null);
}

final CustomChannel currentChannel = getItem(position);

final TextView nowTitle = (TextView) retval.findViewById(R.id.channel_item_current_show_title);
final TextView nowPlayTime = (TextView) retval.findViewById(R.id.channel_item_current_show_play_time);
final TextView nextTitle = (TextView) retval.findViewById(R.id.channel_item_next_show_title);
final TextView nextPlayTime = (TextView) retval.findViewById(R.id.channel_item_next_show_play_time); 

ArrayList<TextView> textViews = new ArrayList<TextView>();
textViews.add(nowTitle);
textViews.add(nowPlayTime);
textViews.add(nextTitle);
textViews.add(nextPlayTime);

EPGLoader.getInstance(mContext).load(textViews, currentChannel);

return retval;

}

那么,我的代码有什么问题?提前谢谢。

编辑:我用普通的Android的ListView替换Horizo​​ntalListView,它可以工作,但我必须在项目中使用Horizo​​ntalListView。任何建议?

编辑2:我奖励回来(Horizo​​ntalListView)并尝试设置一些UI控制器的背景色,猜猜是什么?它更新了。它不会更新文本属性!为什么???? enter image description here

0 个答案:

没有答案