如何在单独的线程上绑定适配器中的数据

时间:2016-11-09 20:42:20

标签: android android-recyclerview

我的custon适配器类

中有内部类ViewHolderStringHolder
private class StringHolder {
    String awards; String countries; String directors; String fullPlot; String genres; String ID;
    String imdbRating; String imdbVotes; String lastUpdated; String languages; String metacritic;
    String posterUrl; String shortPlot; String rating; String releaseDate; String runtime; String writers;
    String title; String imdbId; String cast;
    public StringHolder(Cursor cursor){
        awards = cursor.getString(cursor.getColumnIndexOrThrow("Awards"));
        countries = cursor.getString(cursor.getColumnIndexOrThrow("Country"));
        directors = cursor.getString(cursor.getColumnIndexOrThrow("Director"));
        fullPlot = cursor.getString(cursor.getColumnIndexOrThrow("FullPlot"));
        genres = cursor.getString(cursor.getColumnIndexOrThrow("Genre"));
        ID = cursor.getString(cursor.getColumnIndexOrThrow("ID"));
        imdbRating = cursor.getString(cursor.getColumnIndexOrThrow("imdbRating"));
        imdbVotes = cursor.getString(cursor.getColumnIndexOrThrow("imdbVotes"));
        lastUpdated = cursor.getString(cursor.getColumnIndexOrThrow("lastUpdated"));
        languages = cursor.getString(cursor.getColumnIndexOrThrow("Language"));
        metacritic = cursor.getString(cursor.getColumnIndexOrThrow("Metacritic"));
        posterUrl = cursor.getString(cursor.getColumnIndexOrThrow("Poster"));
        shortPlot = cursor.getString(cursor.getColumnIndexOrThrow("Plot"));
        rating = cursor.getString(cursor.getColumnIndexOrThrow("Rating"));
        releaseDate = cursor.getString(cursor.getColumnIndexOrThrow("Released"));
        runtime = cursor.getString(cursor.getColumnIndexOrThrow("Runtime"));
        writers = cursor.getString(cursor.getColumnIndexOrThrow("Writer"));
        title = cursor.getString(cursor.getColumnIndexOrThrow("Title"));
        imdbId = cursor.getString(cursor.getColumnIndexOrThrow("imdbID"));
        cast = cursor.getString(cursor.getColumnIndexOrThrow("Actors"));

    }
}

private class ViewHolder {
    TextView cast; TextView title; TextView plot; TextView imdbratings; TextView votes;
    ImageView bookmark; ImageView share; ImageView IMDBProfile; FlowLayout flowLayout;
    TextView releaseDate; TextView directors; TextView countries; TextView genres;
    public ViewHolder(View view){
        genres = (TextView) view.findViewById(R.id.genres);
        countries = (TextView) view.findViewById(R.id.countries);
        directors = (TextView) view.findViewById(R.id.directors);
        releaseDate = (TextView) view.findViewById(R.id.releaseDate);
        title = (TextView) view.findViewById(R.id.Title);
        plot = (TextView) view.findViewById(R.id.plot);
        imdbratings = (TextView) view.findViewById(R.id.rating);
        votes = (TextView) view.findViewById(R.id.votes);
        flowLayout = (FlowLayout) view.findViewById(R.id.hash_tag_layout);
        bookmark = (ImageView)view.findViewById(R.id.bookmark);
        share = (ImageView)view.findViewById(R.id.share);
        IMDBProfile = (ImageView)view.findViewById(R.id.IMDBProfile);
        cast = (TextView) view.findViewById(R.id.cast);
    }
}

我将StringHolder(从我的数据库中查询)中的字符串设置为我的cusotm适配器的ViewHolder方法中bindView中的文本视图

public void bindView(final View view, final Context context, final Cursor cursor) {

    // Get recycled viewHolder
    final ViewHolder viewHolder  =   (ViewHolder) view.getTag();

    // Bind strings to views in viewHolder
    StringHolder stringHolder = new StringHolder(cursor);
    viewHolder.title.setText(stringHolder.title);
    viewHolder.plot.setText(parsePlot(stringHolder.shortPlot, stringHolder.fullPlot));
    viewHolder.imdbratings.setText(stringHolder.imdbRating + "/10");
    viewHolder.votes.setText(formatNumbers(stringHolder.imdbVotes));
    viewHolder.countries.setText(stringHolder.countries);
    viewHolder.directors.setText(stringHolder.directors);
    viewHolder.releaseDate.setText(parseDate(stringHolder.releaseDate));
    viewHolder.genres.setText(stringHolder.genres);
    viewHolder.cast.setText(stringHolder.cast);

}

问题是我的主要工作是做大量的工作和跳帧。我尝试在新线程中绑定视图,如此

public void bindView(final View view, final Context context, final Cursor cursor) {

    // Get recycled viewHolder
    final ViewHolder viewHolder  =   (ViewHolder) view.getTag();

    // Bind strings to views in viewHolder
    new Thread() {
        @Override
        public void run() {

            StringHolder stringHolder = new StringHolder(cursor);
            viewHolder.title.setText(stringHolder.title);
            viewHolder.plot.setText(parsePlot(stringHolder.shortPlot, stringHolder.fullPlot));
            viewHolder.imdbratings.setText(stringHolder.imdbRating + "/10");
            viewHolder.votes.setText(formatNumbers(stringHolder.imdbVotes));
            viewHolder.countries.setText(stringHolder.countries);
            viewHolder.directors.setText(stringHolder.directors);
            viewHolder.releaseDate.setText(parseDate(stringHolder.releaseDate));
            viewHolder.genres.setText(stringHolder.genres);
            viewHolder.cast.setText(stringHolder.cast);

        }
    }.start();

}

现在我收到此错误

  

只有创建视图层次结构的原始线程才能触及其视图。

任何想法如何修复错误,同时在单独的线程中维护额外的工作?

修改

这是我的newView方法

// Apply recycling to a view container
public View newView(Context context, Cursor cursor, ViewGroup parent) {

    View view = LayoutInflater.from(context).inflate(R.layout.list_item, parent, false);
    ViewHolder viewHolder = new ViewHolder(view);
    view.setTag(viewHolder);

    return view;
}

2 个答案:

答案 0 :(得分:0)

使用runOnUiThread()

runOnUiThread(new Runnable() {

    @Override
    public void run() {
        StringHolder stringHolder = new StringHolder(cursor);
        viewHolder.title.setText(stringHolder.title);
        viewHolder.plot.setText(parsePlot(stringHolder.shortPlot,stringHolder.fullPlot));
        viewHolder.imdbratings.setText(stringHolder.imdbRating + "/10");
        viewHolder.votes.setText(formatNumbers(stringHolder.imdbVotes));
        viewHolder.countries.setText(stringHolder.countries);
        viewHolder.directors.setText(stringHolder.directors);
        viewHolder.releaseDate.setText(parseDate(stringHolder.releaseDate));
        viewHolder.genres.setText(stringHolder.genres);
        viewHolder.cast.setText(stringHolder.cast);               
    }
});

答案 1 :(得分:0)

将整个视图绑定移动到不同的线程上并不是一个好主意。设置要查看的文本并不是创建StringHolder的昂贵操作。您可以 {@ 3}}在doInBackground方法中读取光标,然后在UI线程上运行onPostExecute,可以为视图设置值