0

我开发了一个联系人应用程序。它完成了普通联系人应用程序应该做的所有事情。总是有改进的机会。我在 Android Emulator 中注意到,当用户安顿下来后,开始加载联系人图像,他已将联系人列表滚动到有可能获得他正在搜索的联系人的区域。因此,我尝试在我的应用程序副本上实现相同的功能。我已经实施了。它的运行非常非常缓慢。正如我推测的那样,我相信应用程序正在多次运行线程,即使它已经检索了导致大滞后的图像。我知道 ASync 任务,但只是出于好奇并检查它是否可以完成,我不想在这里实现它。这是 MainActivity 的源代码。

package com.example.contact;

import java.io.InputStream;
import java.util.ArrayList;



import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.ContactsContract.Contacts;
import android.app.ListActivity;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.AbsListView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;

public class MainActivity extends ListActivity {

    ListView listview;
    private boolean mPaused;
    private MyAdapter mAdapter;
    private View view;
    private boolean running = false;
    final private ArrayList<String> con_ids = new ArrayList<String>();
    private Context context;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);


        listview = getListView();
        context = this;

        Cursor c = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, 
                                              null, 
                                              null, 
                                              null, 
                                              ContactsContract.Contacts.DISPLAY_NAME+" ASC");


        if(c!=null)
        {
            for(c.moveToFirst();!c.isAfterLast();c.moveToNext()){
                con_ids.add(c.getString(c.getColumnIndex(ContactsContract.Contacts._ID)));
            }
        }

        mAdapter = new MyAdapter(this, android.R.layout.simple_list_item_1, con_ids);
        listview.setAdapter(mAdapter);
        listview.setOnScrollListener(makeScrollListener());
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

    public void setEnabled(boolean enabled) {
        mPaused = !enabled;
    }

    private AbsListView.OnScrollListener makeScrollListener() {
        return new AbsListView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView absListView, int scrollState) {
                setEnabled(scrollState != AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
                running = false;
            }

            @Override
            public void onScroll(AbsListView absListView, int i, int i1, int i2) {

                String log = "";
                Log.d(log, "Scroll First Item" + i);
                Log.d(log, ""+ listview.getChildCount());           

                final int want = i;
                running = true;

                runOnUiThread(new Thread(new Runnable() {
                    int totalChild = listview.getChildCount();
                    int first = listview.getFirstVisiblePosition() - listview.getHeaderViewsCount();
                    int toRetrieve = want-first;
                    int id;
                    long con_id;
                    Bitmap thumbnail;
                    final ListView list = listview;

                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        while(running)
                        {
                            if(!(toRetrieve<0||toRetrieve>=totalChild))
                            {
                                id = want+toRetrieve;
                                con_id = Long.valueOf(con_ids.get(id));
                                Uri ContactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, con_id);
                                InputStream stream = ContactsContract.Contacts.openContactPhotoInputStream(context.getContentResolver(), ContactUri);
                                thumbnail = BitmapFactory.decodeStream(stream);
                                if(thumbnail == null)
                                {
                                    toRetrieve++;
                                    continue;
                                }
                                else
                                {
                                    View view = list.getChildAt(toRetrieve);
                                    if(view == null)
                                    {
                                        toRetrieve++;
                                        continue;
                                    }
                                    else
                                    {
                                        ImageView iamge = (ImageView) view.findViewById(R.id.contact_iamge);
                                        iamge.setImageBitmap(thumbnail);
                                    }
                                    toRetrieve++;
                                }

                            }
                            else
                            {
                                running = false;
                            }
                        }
                    }
                }));
            }
        };
    }

}

MyAdapter 的代码,

package com.example.contact;

import java.util.ArrayList;

import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.provider.ContactsContract;
import android.provider.ContactsContract.Contacts;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebView.FindListener;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

public class MyAdapter extends ArrayAdapter<String> {

    private Context context;
    private ListView listview;
    private ArrayList<String> ids;
    private LayoutInflater infl;
    private String displayname;
    private String maindetail;
    private SimplifiedContact contact;
    private Drawable drawable;


    public MyAdapter(Context context, int ResourceId, ArrayList<String> list)
    {
        super(context, ResourceId, list);
        this.context = context;
        ids = list;
        infl = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        drawable = context.getResources().getDrawable(R.drawable.person);
    }

    static class ViewHolder
    {
        public ImageView image;
        public TextView display_name;
        public TextView main_detail;
    }

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

        View row = convertView;
        contact = new SimplifiedContact(context, Long.valueOf(ids.get(position)));

        if(row == null)
        {
            row = infl.inflate(R.layout.single_cell, parent, false);
            ViewHolder viewHolder = new ViewHolder();

            viewHolder.display_name =(TextView) row.findViewById(R.id.disp_name);
            viewHolder.main_detail = (TextView) row.findViewById(R.id.main_detail);
            viewHolder.image = (ImageView)row.findViewById(R.id.contact_iamge);
            row.setTag(viewHolder);

        }

        ViewHolder holder = (ViewHolder) row.getTag();
        holder.display_name.setText(contact.getDisplayName());
        holder.main_detail.setText(contact.getMainDetail());
        holder.image.setBackgroundDrawable(drawable);

        return row;
    }


}

我想知道,如何减少这种滞后。提前致谢。

4

1 回答 1

0

您为什么不尝试获取您在 runOnUiThread 中创建的 Thread 实例并将其放在一个字段中,在 onCreate 中对其进行初始化。我认为您正在创建几个没有用的线程实例。

public class MainActivity extends ListActivity {

ListView listview;
private boolean mPaused;
private MyAdapter mAdapter;
private View view;
private boolean running = false;
final private ArrayList<String> con_ids = new ArrayList<String>();
private Context context;
Thread uiThread;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);


    listview = getListView();
    context = this;

    Cursor c = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, 
                                          null, 
                                          null, 
                                          null, 
                                          ContactsContract.Contacts.DISPLAY_NAME+" ASC");


    if(c!=null)
    {
        for(c.moveToFirst();!c.isAfterLast();c.moveToNext()){
            con_ids.add(c.getString(c.getColumnIndex(ContactsContract.Contacts._ID)));
        }
    }

    uiThread = new Thread(new Runnable() {
        int totalChild = listview.getChildCount();
        int first = listview.getFirstVisiblePosition() - listview.getHeaderViewsCount();
        int toRetrieve = want-first;
        int id;
        long con_id;
        Bitmap thumbnail;
        final ListView list = listview;

        @Override
        public void run() {
            // TODO Auto-generated method stub
            while(running)
            {
                if(!(toRetrieve<0||toRetrieve>=totalChild))
                {
                    id = want+toRetrieve;
                    con_id = Long.valueOf(con_ids.get(id));
                    Uri ContactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, con_id);
                    InputStream stream = ContactsContract.Contacts.openContactPhotoInputStream(context.getContentResolver(), ContactUri);
                    thumbnail = BitmapFactory.decodeStream(stream);
                    if(thumbnail == null)
                    {
                        toRetrieve++;
                        continue;
                    }
                    else
                    {
                        View view = list.getChildAt(toRetrieve);
                        if(view == null)
                        {
                            toRetrieve++;
                            continue;
                        }
                        else
                        {
                            ImageView iamge = (ImageView) view.findViewById(R.id.contact_iamge);
                            iamge.setImageBitmap(thumbnail);
                        }
                        toRetrieve++;
                    }

                }
                else
                {
                    running = false;
                }
            }
        }
    });

    mAdapter = new MyAdapter(this, android.R.layout.simple_list_item_1, con_ids);
    listview.setAdapter(mAdapter);
    listview.setOnScrollListener(makeScrollListener());
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.activity_main, menu);
    return true;
}

public void setEnabled(boolean enabled) {
    mPaused = !enabled;
}

private AbsListView.OnScrollListener makeScrollListener() {
    return new AbsListView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(AbsListView absListView, int scrollState) {
            setEnabled(scrollState != AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
            running = false;
        }

        @Override
        public void onScroll(AbsListView absListView, int i, int i1, int i2) {

            String log = "";
            Log.d(log, "Scroll First Item" + i);
            Log.d(log, ""+ listview.getChildCount());           

            final int want = i;
            running = true;

            runOnUiThread(uiThread);
        }
    };
}

}

于 2013-03-16T22:09:12.577 回答