AsyncTask 在自定义适配器中不起作用

Posted

技术标签:

【中文标题】AsyncTask 在自定义适配器中不起作用【英文标题】:AsyncTask doesn`t work in custom adapter 【发布时间】:2015-12-28 10:53:30 【问题描述】:

我正在使用自定义适配器从 SQLite 创建销售点列表

    dbHelper = new YourVoiceDatabaseHelper(getActivity());

    pointsList = new ArrayList<Point>();
    List<Point> pl = new ArrayList<Point>();
    PointsListArrayAdapter adapter;

    adapter =  new PointsListArrayAdapter(getActivity().getApplicationContext(),
            pointsList,
            getActivity().getFilesDir(),
            getResources().getString(R.string.Local_Resorces_Folder),
            dbHelper);

    pointsListView.setAdapter(adapter);

    pl =  dbHelper.getAllPoints();

    if(myLocation != null) 
        for (Point el : pl) 
            elLocation.setLatitude(Double.parseDouble(el.getLatitude()));
            elLocation.setLongitude(Double.parseDouble(el.getLongtitude()));

            if (myLocation.distanceTo(elLocation) <= 999) 
                pointsList.add(el);
            
        
     else 
        Toast.makeText(getActivity(), "Не удалось определить ваше местоположение, проверте ваши разрешения и настройки",
                Toast.LENGTH_LONG).show();
     adapter.notifyDataSetChanged();

对于自定义适配器,我在其中使用它发送我的数据库广告实例,这会减慢我的主要步伐。我正在尝试在适配器中使用 AsyncTask 从数据库中获取图像路径并设置图像,但 Async 绝对什么都不做

    package ua.com.it_artel.tvoy_golos.service;

公共类 PointsListArrayAdapter 扩展 BaseAdapter

Context context;
private List<Point> pointsList;
private File appFolder;
private String resoursesFolder;
private YourVoiceDatabaseHelper dbHelper;
private String imagePath;

public PointsListArrayAdapter(Context context, List<Point> pointsList, File appFolder, String resoursesFolder, YourVoiceDatabaseHelper dbHelper) 
    this.context = context;
    this.pointsList = pointsList;
    this.appFolder = appFolder;
    this.resoursesFolder = resoursesFolder;
    this.dbHelper = dbHelper;


@Override
public int getCount() 
    return pointsList.size();


@Override
public Object getItem(int position) 
    return pointsList.get(position);


@Override
public long getItemId(int position) 
    return pointsList.get(position).getId();


static class ViewHolder 
    ImageView image;
    TextView adress;
    TextView name;
    TextView distance;
    Location elLocation;
    Point point;


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

    ViewHolder viewHolder;
    View rowView = convertView;
    if(convertView == null)
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        rowView = inflater.inflate(R.layout.list_element_layout_type_1, parent, false);

        viewHolder = new ViewHolder();
        viewHolder.elLocation = new Location("");

        viewHolder.image = (ImageView) rowView.findViewById(R.id.item_image);

        viewHolder.adress = (TextView) rowView.findViewById(R.id.item_text);

        viewHolder.name = (TextView) rowView.findViewById(R.id.item_name);

        viewHolder.distance = (TextView) rowView.findViewById(R.id.item_distance);

        rowView.setTag(viewHolder);
     else 
        viewHolder = (ViewHolder) rowView.getTag();
    

    viewHolder.elLocation.setLatitude(Double.parseDouble(pointsList.get(position).getLatitude()));
    viewHolder.elLocation.setLongitude(Double.parseDouble(pointsList.get(position).getLongtitude()));

    viewHolder.point = pointsList.get(position);
    new AdapterImageSetter().execute(viewHolder);

    viewHolder.adress.setText(pointsList.get(position).getAddress());

    viewHolder.name.setText(dbHelper.getPartnerByUID(pointsList.get(position).getPartnerUid()).getName());

    viewHolder.distance.setText(String.valueOf(Math.round(MyLocationListener.myLocation.distanceTo(viewHolder.elLocation))) + " м");

    return rowView;



private class AdapterImageSetter extends AsyncTask<ViewHolder, Void, ViewHolder> 

    @Override
    protected ViewHolder doInBackground(ViewHolder... params) 
        ViewHolder viewHolder = params[0];

        imagePath = dbHelper.getPointsPartnerImage(viewHolder.point.getPartnerUid());

        if (imagePath.equals("")) 
            viewHolder.image.setImageResource(R.drawable.no_image);
         else 
            Drawable dr = Drawable.createFromPath(appFolder.getPath() + "/" + resoursesFolder + "/" + imagePath);
            viewHolder.image.setImageDrawable(dr);
        
        return viewHolder;
    

我在 AsyncTask 和 Runnable 中尝试了不同的变体,但它不起作用,就像没有代码一样。希望你理解我的英语并且有人给建议

【问题讨论】:

阅读Loaders,例如CursorLoader 【参考方案1】:

你不能在doInBackground方法中进行ui相关的操作,ui相关的操作只能使用onpostexcecute方法 更多关于异步任务http://developer.android.com/reference/android/os/AsyncTask.html

在你的代码中你设置了imege

if (imagePath.equals("")) 
            viewHolder.image.setImageResource(R.drawable.no_image);
         else 
            Drawable dr = Drawable.createFromPath(appFolder.getPath() + "/" + resoursesFolder + "/" + imagePath);
            viewHolder.image.setImageDrawable(dr);
        

只需将此代码添加到onPostExecute

【讨论】:

他也可以使用 runOnUIThread() 从 doInBackground() 中实现。 是的,但是如果aynchtask为您提供所有结构,为什么要这样做..它将被使用,但在这里不是必需的【参考方案2】:

成功了!我还在异步中添加了一些代码,一切正常,但出现图像和名称需要太多时间。

私有类 AdapterImageSetter 扩展 AsyncTask

    @Override
    protected ViewHolder doInBackground(ViewHolder... params) 
        ViewHolder viewHolder = params[0];

        viewHolder.imagePath = dbHelper.getPointsPartnerImage(viewHolder.point.getPartnerUid());

        viewHolder.pointName = dbHelper.getPartnerByUID(viewHolder.point.getPartnerUid()).getName();
        return viewHolder;
    

    @Override
    protected void onPostExecute(ViewHolder viewHolder) 

        if (viewHolder.imagePath.equals("")) 
            viewHolder.image.setImageResource(R.drawable.no_image);
         else 
            Drawable dr = Drawable.createFromPath(appFolder.getPath() + "/" + resoursesFolder + "/" + viewHolder.imagePath);
            viewHolder.image.setImageDrawable(dr);
        

        viewHolder.name.setText(viewHolder.pointName);

        Log.i("IMAGE PATH", viewHolder.imagePath);
        Log.i("PARTNER UID", viewHolder.point.getPartnerUid());
    

更多信息:当您打开应用程序时,此列表显示在第一个屏幕上。 在第一个活动中,我替换了片段并删除了我正在执行所有操作的片段。对如何加快 AsyncTask 中的操作有任何想法吗?

非常感谢您的帮助!

【讨论】:

对于列表视图或适配器中的设置和图像,您最好使用一些库,例如 picasso square.github.io/picasso 或您发现更好的库 非常感谢,很棒的库,但是我从数据库加载图像路径和点名称时遇到问题,它一直在吃=(

以上是关于AsyncTask 在自定义适配器中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

ListView 和自定义适配器在 Kotlin 中不起作用

getView() 在我的自定义列表视图中不起作用

UITapGestureRecognizer 在自定义 UIView 中不起作用

UIScreenEdgePanGestureRecognizer 在自定义键盘扩展中不起作用

TapGestures 在自定义 TableViewCell 中不起作用

安全区域在自定义 TabBarController 的 ViewController 中不起作用