带有AsyncTask的ListView ViewHolder:postExecute setText阻止UI

时间:2014-02-20 11:04:19

标签: android listview android-asynctask

我在新Galaxy Note 10.1 2014版中遇到滞后问题。我认为这是该设备中的android 4.3版本,因为在2013版本(android 2.1.3)中它的效果要好得多。

事情是:

我已经实现了视图模式以在列表视图中显示一些数据。我正在使用SUP(sybase Unwired Server)对象API从ultralite数据库中检索数据。当我有数据时,必须进行一些计算,因此,我会显示列表,并抛出一个asyncTask来计算数据。

问题在于,setText("Whatever")中的简单postExecute会阻止用户界面。 Galaxy Note 2013的版本中没有发生这种情况......

一些代码:

GetView:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View row = convertView;
    ViewHolder holder;
    if (row == null) {
        if(Constants.DEBUG_ENABLED) Log.d(Constants.LOG_TAG, "NEW ROW");
        row = _Inflater
                .inflate(R.layout.row_commercialconditions_search_result,
                        parent, false);             
        holder = new ViewHolder();              
        holder.vView= (LinearLayout) row.findViewById(R.id.row_valueDisc_view);
        holder.vAgrup = (TextView) row
                .findViewById(R.id.row_valueDisc_agrup);
        [...]
        row.setTag(holder);

    } else {
        if(Constants.DEBUG_ENABLED) Log.d(Constants.LOG_TAG, "OLD ROW");
        holder = (ViewHolder)row.getTag();
    }           

    ConditionListItem valDisc = _Objects.get(position);

    holder.position = position;

    holder.vDist.setText(valDisc.getConditionDist());
    holder.vObjGroup.setText(valDisc.getConditionObjGroup());
    holder.vRate.setText(valDisc.getConditionRate());
    [...]
    holder.vReason.setText(valDisc.getConditionReason());
    holder.vAuthLvl.setText(valDisc.getConditionAuthLvl());

    new LoadConditionsHolderAsync(valDisc, holder,position).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);          
    return row;
}
  

ViewHolder:

static class ViewHolder {       
    TextView vProduct;
    TextView vCondType;
    TextView vVal;
    TextView vDatefrom;
    TextView vDateTo;
    TextView vDiscount;
    TextView vDiscMode;
    TextView vPeriod;
    TextView vEquidesc;
    TextView vAuthLvl;
    CheckBox vRevDamm;
    CheckBox vRevDistr;

    TextView vDist;
    TextView vObjGroup;
    TextView vReason;
    TextView vRate;
    TextView vAgrup;
    TextView vAcum;
    TextView vIncomp;

    RelativeLayout vProgress;
    int position;
    public LinearLayout vView;
}
  

的AsyncTask:

protected class LoadConditionsHolderAsync extends AsyncTask<Void, Void, String>{

    private ViewHolder mV;
    private ConditionListItem mCond;
    private int mPosition;
    private Resources mResources;
    private String mPackageName;

    String mAgrup;
    String mProduct;
    String mDatefrom;
    String mTypeCond;
    String mDateTo;
    String mDiscount;
    String mDiscMode;
    String mPeriod;
    String mState;
    String mReason;
    String mAproveLevel;
    boolean mCentral;
    String mEquidesc;
    boolean mRevDamm;
    boolean mRevDistr;
    int mBackground;



    public LoadConditionsHolderAsync (ConditionListItem cond, ViewHolder vh, int position){
        mV=vh;
        mCond = cond;
        mPosition=position;         
    }

    @Override
    protected void onPreExecute() {
        mV.vProgress.setVisibility(View.VISIBLE);
        super.onPreExecute();
    }

    @Override
    protected String doInBackground(Void... params) {
            if(isCancelled()){
                return null;
            }
            mTypeCond = ApplicationStatus.getHelpSearch(Constants.HV_CONDITION_TYPE, mCond.getConditionData().getTIPO());
            mDiscMode = ApplicationStatus.getHelpSearch(Constants.HV_CONDITION_MODALITY, mCond.getConditionData().getMODALIDAD());
            mPeriod = ApplicationStatus.getHelpSearch(Constants.HV_CONDITION_PERIOD, mCond.getConditionData().getPERIODO());
            mState = ApplicationStatus.getHelpSearch(Constants.HV_CONDITION_STATE, mCond.getConditionData().getESTADO());
            mReason = ApplicationStatus.getHelpSearch(Constants.HV_CONDITION_REASON, mCond.getConditionData().getMOTIVO());
            mAproveLevel = ApplicationStatus.getHelpSearch(Constants.HV_CONDITION_APPROVAL_LEVEL, mCond.getConditionData().getNIVEL_APROB());
            return "OK";

    }

     @Override
    protected void onPostExecute(String result) {
        if (result!=null && mV.position == mPosition) {
            if(Constants.DEBUG_ENABLED) Log.d(Constants.LOG_TAG, "Setting "+mV.position+"...");     
            mV.vCondType.setText(mTypeCond);
            mV.vDiscMode.setText(mDiscMode);
            mV.vPeriod.setText(mPeriod);
            mV.vVal.setText(mState);
            mV.vReason.setText(mReason);
            mV.vAuthLvl.setText(mAproveLevel);
        }
        super.onPostExecute(result);

    }

}

在2014版本中,我看到很多消息如“AbsListView: unregisterIRlistener()被称为”,我不知道这是否相关......

有人能帮助我吗?

2 个答案:

答案 0 :(得分:0)

不要在onBackground()和onPostExecute()中使用共享变量。

应该从doInBackground()返回onPostExecute中所需的所有变量。 然后从onPostExecute(需要的参数)

接收值作为函数的输入参数

答案 1 :(得分:0)

我找到了解决方案。问题是清单中的targetSdkVersion。使用新设备(Android 4.3),我有targetSdkVersion = 16(Android 4.1),我不确切知道原因,但这导致整个应用程序出现后台线程问题。

所以我更新到targetSdkVersion = 18(Android 4.3),现在一切顺利。

此致