I use AsyncTask to query an SQLite database - contacts.
When I run that code on the android emulator it works fine (probably because I have less contacts added there), but when I run it on my mobile (which it has approx 500 contacts) the app runs slow.
Any help would be appreciated. Thank you.
The Code is below.
private class loadMoreListView extends AsyncTask<Void, Void, Void> {
ArrayList<Contact> contactsx = new ArrayList<Contact>();
@Override
protected void onPreExecute() {
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Please wait..");
pDialog.setIndeterminate(true);
pDialog.setCancelable(false);
pDialog.show();
lv = (ListView) findViewById(R.id.blacklist);
}
@Override
protected void onPostExecute(Void unused) {
// closing progress dialog
lv.setAdapter(adapter);
pDialog.dismiss();
}
@Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
ArrayList<Contact> contactItemsTemp = new ArrayList<Contact>();
adapter = new EfficientAdapter(MainActivity.this, contactItems);
DatabaseHandler db = new DatabaseHandler(MainActivity.this);
String name = "";
String id = "";
String phoneNumber = "";
// Cursor cursor = null;
List<Integer> mycontactID;
mycontactID = db.getAllIDs();
Iterator value = mycontactID.iterator();
while (value.hasNext()) {
int mg=(Integer)value.next();
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null,
null, null, null);
// Log.d("edw",Integer.toString(mg));
if (cur.getCount() > 0) {
while (cur.moveToNext()) {
id = cur.getString(cur
.getColumnIndex(ContactsContract.Contacts._ID));
if (id.equals((mg)))
;
{
name = cur
.getString(cur
.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
if (Integer
.parseInt(cur.getString(cur
.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
Cursor pCur = cr
.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID
+ " = ?",
new String[] { id }, null);
while (pCur.moveToNext()) {
Log.d("number",
pCur.getString(pCur
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)));
// Do something with phones
phoneNumber = pCur
.getString(pCur
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
}
contactItemsTemp.add(new Contact(Integer
.parseInt(id), name, phoneNumber));
pCur.close();
Log.d("Name", name);
}
}
}
cur.close();
}
}
// na kanw to temp contactItems
List<Integer> messagesx;
messagesx = db.getAllIDs();
String namex = "";
String phonex = "";
for (Integer mg : messagesx) {
for (int i = 0; i < contactItemsTemp.size(); i++) {
if (contactItemsTemp.get(i).getID() == mg) {
namex = contactItemsTemp.get(i).getContactName();
phonex = contactItemsTemp.get(i).getPhoneNumber();
}
}
contactsx.add(new Contact(mg, namex, phonex));
}
adapter = new EfficientAdapter(MainActivity.this, contactsx);
db.close();
return null;
}
}
public static class EfficientAdapter extends ArrayAdapter<Contact>
implements Filterable {
private LayoutInflater mInflater;
// private Bitmap mIcon1;
private final Context context;
private final ArrayList<Contact> values;
public EfficientAdapter(Context context, ArrayList<Contact> values) {
// Cache the LayoutInflate to avoid asking for a new one each time.
super(context, R.layout.myobject, values);
mInflater = LayoutInflater.from(context);
this.context = context;
this.values = values;
}
/**
* Make a view to hold each row.
*
* @see android.widget.ListAdapter#getView1(int, android.view.View,
* android.view.ViewGroup)
*/
@Override
public View getView(final int position, View convertView,
ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.myobject, null);
holder = new ViewHolder();
holder.contact = (TextView) convertView
.findViewById(R.id.contact);
holder.ph_num = (TextView) convertView
.findViewById(R.id.ph_num);
convertView.setTag(holder);
}
else {
// Get the ViewHolder back to get fast access to the TextView
// and the ImageView.
holder = (ViewHolder) convertView.getTag();
}
convertView.setOnLongClickListener(new View.OnLongClickListener() {
private int pos = position;
@Override
public boolean onLongClick(View v) {
// TODO Auto-generated method stub
// prepare the alert box
AlertDialog.Builder alertbox = null;
alertbox = new AlertDialog.Builder(context);
// set the message to display
alertbox.setMessage("Are you sure you want to remove the contact from the blacklist?");
// add a neutral button to the alert box and assign a click
// listener
alertbox.setNeutralButton("OK",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
// TODO Auto-generated method stub
Toast.makeText(context,
"Ok button pressed " + pos,
Toast.LENGTH_SHORT).show();
DatabaseHandler db = new DatabaseHandler(
context);
db.deleteContact(values.get(position)
.getID());
db.close();
}
});
alertbox.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
// TODO Auto-generated method stub
Toast.makeText(context,
"Cancel button pressed " + pos,
Toast.LENGTH_SHORT).show();
}
});
alertbox.show();
return true;
}
});
convertView.setOnClickListener(new OnClickListener() {
private int pos = position;
@Override
public void onClick(View v) {
// Toast.makeText(context, "Click-" + pos,
// Toast.LENGTH_SHORT)
// .show();
}
});
holder.contact.setText(getItem(position).getContactName());
holder.ph_num.setText(getItem(position).getPhoneNumber());
return convertView;
}
static class ViewHolder {
TextView contact;
TextView ph_num;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return values.size();
}
@Override
public Contact getItem(int position) {
// TODO Auto-generated method stub
return values.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
@Override
public Filter getFilter() {
// TODO Auto-generated method stub
return null;
}
public void add(Contact con) {
values.add(con);
notifyDataSetChanged();
}
public void replace(int index, Contact con) {
values.set(index, con);
notifyDataSetChanged();
}
public void clear() {
values.clear();
notifyDataSetChanged();
}
public void remove(Contact con) {
values.remove(con);
notifyDataSetChanged();
}
}
Well, I am not sure about the exception, but it seems like you are trying to add contacts to your contactx arraylist before you initialize it. You declare it as an instance variable, but do not initialize it until the very end of your doInBackground() method. That would throw null pointer...
try putting the line..
contactx = new ArrayList<Contact>();
In your onPreExecute() method.
lv = (ListView) findViewById(R.id.blacklist);
I would take a look at this line. You're trying to find your list view from a nested class. Although this will be run on the UI thread, AsyncTask is still not an activity. I beleive your null point is becuase your listview reference is null as an instance of AsyncTask cannot retreive views.
why is the adapter created twice (yet used only once) , and inside the runInBackground? should it be created only after the raw data was fetched , in the onPostExecute?
is it possible that you didn't implement the adapter nicely ? have you watched the "the world of listView" video of google? please show the adapter's code.
what is the exception of the crash?
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.