1

Я создаю sms-приложение, в котором перечислены контакты, имя, сообщение, дата разговора. Я использую пользовательский адаптер список them.Below является кодМедленная загрузка ListView с изображением и текстом. Как реализовать loader.callbacks?

public class ConvRowAdapter extends ArrayAdapter<ConvItem> { 
private Context my_context; 
// View lookup cache 
private static class ViewHolder { 
    TextView name,body,date; 
    ImageView img; 
} 
public ConvRowAdapter(Context context, ArrayList<ConvItem> ConvItems) { 
    super(context, R.layout.convitem, ConvItems); 
    my_context=context; 
} 
@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    // Get the data item for this position 
    ConvItem ConvItem = getItem(position);  
    // Check if an existing view is being reused, otherwise inflate the view 
    ViewHolder viewHolder; // view lookup cache stored in tag 
    if (convertView == null) { 
     viewHolder = new ViewHolder(); 
     LayoutInflater inflater = LayoutInflater.from(getContext()); 
     convertView = inflater.inflate(R.layout.convitem, null); 
     viewHolder.img = (ImageView) convertView.findViewById(R.id.iv_photo); 
     viewHolder.name = (TextView) convertView.findViewById(R.id.tv_name); 
     viewHolder.date = (TextView) convertView.findViewById(R.id.tv_date); 
     viewHolder.body = (TextView) convertView.findViewById(R.id.tv_body); 
     convertView.setTag(viewHolder); 
    } else { 
     viewHolder = (ViewHolder) convertView.getTag(); 
    } 
    // Populate the data into the template view using the data object 
    if(ConvItem.getPhotoUri()!=null) 
    { 
     Bitmap bitmap=BitmapFactory.decodeStream(my_context.getContentResolver().openInputStream(ConvItem.getPhotoUri())); 
     viewHolder.img.setImageBitmap(bitmap);//Image is set 
    } 
    else 
    { 
     Bitmap bitmap=BitmapFactory.decodeResource(my_context.getResources(),R.drawable.contact_blue); 
     viewHolder.img.setImageBitmap(bitmap); 
    } 
    if(ConvItem.getDisplayName()==null) 
    viewHolder.name.setText(ConvItem.getAddress());//Phone number set 
    else 
    viewHolder.name.setText(ConvItem.getDisplayName());//If phone number exists in contacts display contact name 
    viewHolder.date.setText(ConvItem.getDate());//set date 
    viewHolder.body.setText(ConvItem.getBody());//setting the body of the message 
    // Return the completed view to render on screen 
    return convertView; 
} 
} 

Это занимает 8-9 секунд, чтобы отобразить список. Есть ли способ улучшить скорость? Если да, напишите правильный способ сделать это.

Заранее спасибо :)

Edited: 

Чтобы проверить, если задержка в загрузке вызвана загрузкой изображений я пытался удалить все фото настройки заявления и побежал it.Still загрузка занимает столько же времени. С помощью simplecursoradapter я мог отображать тело, дату и сообщение без задержки. Но для отображения фотографии с ними я попытался использовать пользовательский адаптер. Это функция, которая возвращает все смс в arraylist.Please проверить эффективность кода:

public ArrayList<ConvItem> getSMS(){ 
    ArrayList<ConvItem> ConvItems = new ArrayList<ConvItem>(); 
    Uri uriSMSURI = Uri.parse("content://mms-sms/conversations?simple=true"); 
    Cursor cur = getActivity().getContentResolver().query(uriSMSURI, null, null, null, 
      "date desc"); 
    cur.moveToFirst(); 
    while (!cur.isAfterLast()) { 
     ConvItem ConvItem = new ConvItem(); 
     String address = null, body = null, dname = null,res=null,id_dummy=null; 
     Long date=null; 
     Uri uriphotoid=null; 
     //to obtain address from canonical-addresses 
     res = cur.getString(cur.getColumnIndex("recipient_ids")); 
     Uri ad =Uri.parse("content://mms-sms/canonical-addresses/"); 
     Cursor curad=getActivity().getContentResolver().query(ad, null,null, null, null); 
     curad.moveToFirst(); 
     while(!curad.isAfterLast()) 
     { 
      id_dummy=curad.getString(curad.getColumnIndexOrThrow("_id")); 
      if(id_dummy.equals(res)) 
      address=curad.getString(curad.getColumnIndexOrThrow("address")); 
      curad.moveToNext(); 
     } 
     curad.close(); 
     body = cur.getString(cur.getColumnIndexOrThrow("snippet")); 
     date = cur.getLong(cur.getColumnIndexOrThrow("date")); 
     Date datenew=new Date(date); 
     String formatted_date=new SimpleDateFormat(" "+"dd/MM/yyyy").format(datenew); 
     thread_id = cur.getString(cur.getColumnIndexOrThrow("_id")); 
     Long ContactID = fetchContactIdFromPhoneNumber(address); 
     //uriphotoid = getPhotoUri(ContactID); 
     dname = getcontactname(address); 
     ConvItem.setDisplayName(dname); 
     ConvItem.setThreadId(thread_id); 
     ConvItem.setAddress(address); 
     //ConvItem.setPhotoUri(uriphotoid); 
     ConvItem.setDate(formatted_date); 
     ConvItem.setBody(body); 
     ConvItems.add(ConvItem); 
     cur.moveToNext(); 
    } 
    cur.close(); 
    return ConvItems; 
    } 

Этой функция работает на моих OnCreate метод в основном классе активности.


Я использовал loader.callbacks для исправления проблемы с задержкой.

public class InboxLoaderFragment extends Fragment implements LoaderCallbacks<Cursor>{ 

private static final int LOADER_ID = 1;//identify which loader 
LoaderManager lm; 
SimpleCursorAdapter mAdapter; 
ListView lv; 
private LoaderManager.LoaderCallbacks<Cursor> mCallbacks; 

public InboxLoaderFragment(){} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
     Bundle savedInstanceState) { 
    View rootview=inflater.inflate(R.layout.inboxloaderfragment,container,false); 
    lv=(ListView)rootview.findViewById(R.id.list); 
    // Create an empty adapter we will use to display the loaded data. 

    String[] uiBindFrom = {"recipient_ids","recipient_ids","snippet"}; 
    int[] uiBindTo = {R.id.iv_photo,R.id.tv_name,R.id.tv_body}; 

    mAdapter = new SimpleCursorAdapter(getActivity(),R.layout.convitem,null,uiBindFrom,uiBindTo, 0); 

    mAdapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() { 

     @Override 
     public boolean setViewValue(View view, Cursor cursor, int columnIndex) { 

      switch(view.getId()) 
      { 
      case R.id.iv_photo: 
       String res=null,address=null; 
       //to obtain address from canonical-addresses 
       res = cursor.getString(cursor.getColumnIndex("recipient_ids")); 
       address=getadd(res); 
       Long ContactID = fetchContactIdFromPhoneNumber(address); 
       Uri uriphotoid = getPhotoUri(ContactID); 
       setcontactimage(uriphotoid,view); 
       //set photo using uri 
       return true; 

      case R.id.tv_name: 
       String res1=null,address1=null; 
       res1 = cursor.getString(cursor.getColumnIndex("recipient_ids")); 
       address1=getadd(res1);//to obtain address from canonical-addresses 
       String dname = getcontactname(address1); 
       if(dname!=null)//contact exits 
       ((TextView)view).setText(dname);//contact exists 
       else 
       ((TextView)view).setText(address1);//set display name 
       return true; 

      case R.id.tv_body: 
       String body = cursor.getString(cursor.getColumnIndexOrThrow("snippet")); 
       ((TextView)view).setText(body);//set message body 
       return true; 

      default: 
      return false; 
      } 
     } 
    }); 
    lv.setAdapter(mAdapter); 
    mCallbacks=this; 
    lm = getLoaderManager(); 
    //Initiating the loader 
    lm.initLoader(LOADER_ID, null,mCallbacks); 
    return rootview; 
} 
@Override 
public android.support.v4.content.Loader<Cursor> onCreateLoader(
     int arg0, Bundle arg1) { 
    Uri baseUri = Uri.parse("content://mms-sms/conversations?simple=true"); 
    return new CursorLoader(getActivity(), baseUri, 
       null, null, null,"date desc"); 
} 
@Override 
public void onLoadFinished(
     android.support.v4.content.Loader<Cursor> arg0, Cursor arg1) { 
    switch (arg0.getId()) { 
     case LOADER_ID: 
     mAdapter.swapCursor(arg1); 
     break; 
    } 
    // The listview now displays the queried data 
} 
@Override 
public void onLoaderReset(android.support.v4.content.Loader<Cursor> arg0) { 

    mAdapter.swapCursor(null); 
} 

}///main activity 

App загружается очень быстро now.But скроллинг laggy.How реализовать viewholder шаблон проектирования внутри пользовательского simplecursoradapter или CursorAdapter?

+0

не используют матрицу для стартеров. используйте курсорный адаптер, поскольку запрос выбора будет быстрее, чем загрузка всех «ConvItem» из db в память. – njzk2

+1

Еще один вопрос с соответствующими ответами: [Lazy load of Images in ListView] (http://stackoverflow.com/q/541966/1590950) – indivisible

+0

вы говорите о simplecursoradapter правильно? Но как вы можете установить фотографию для каждой строки? –

ответ

2

Есть ли способ улучшить скорость?

Загрузите свою фотографию в фоновый поток, возможно, используя библиотеку управления изображениями, такую ​​как Picasso.

Помимо этого, используйте Traceview и другие инструменты, чтобы определить, где ваши проблемы лежат.

+0

Можете ли вы продемонстрировать движущую загрузку фотографий в фоновый поток? –

+0

@ user3370397: Вы можете щелкнуть ссылку в моем ответе и прочитать документацию Пикассо. В их репозитории GitHub есть пример приложения IIRC, а вот еще один (также демонстрирующий использование их библиотеки дооснащения): https://github.com/commonsguy/cw-omnibus/tree/master/HTTP/Picasso – CommonsWare

+0

спасибо за комментарий . Но когда я попытался удалить все утверждения настройки фотографий и запустил код, он принимает такое же количество задержки. Пожалуйста, проверьте отредактированный пост :) –

Смежные вопросы