我自己的消息应用适配器出错



我正在开发自己的消息应用程序,可以向服务器发送和接收消息。

我正在使用一个名为状态的整数数组,表示消息是传出或传入。

当我在MessageActivity下一行注释时,listview显示了一些消息,但是当我向下滚动时,我的应用程序崩溃了,我得到编排错误。

holder.ivReceiveUser.setImageBitmap(BitmapFactory.decodeFile(userImage));           

此外,当我不评论以上行,我得到BitmapFactory错误。(我确定imagePath是true,因为我在其他活动中使用了它)

MessageActivity

private void initListview()
{
    lv = (ListView) findViewById(R.id.lv_messages);
    MessagesList = dbh.getAllMessagesOfSpecificUser(TargetUserID);
    final String img = TargetModel.getImagePath();
    String username = TargetModel.getName();
    String[] Content = new String[MessagesList.size()]; 
    String[] MessageID = new String[MessagesList.size()];
    String[] SendDate = new String[MessagesList.size()];
    int[] Status = new int[MessagesList.size()];
    String[] ReadDate = new String[MessagesList.size()];
    for(int i=0; i<MessagesList.size(); i++)
    {
        Content[i] = MessagesList.get(i).getContent(); 
        MessageID[i] = MessagesList.get(i).getMessageID();
        SendDate[i] = MessagesList.get(i).getSendDate();
        Status[i] = MessagesList.get(i).getStatus();
        ReadDate[i] = MessagesList.get(i).getReadDate();
    }       
    mAdapter = new AdapterMessagesII(MessagesActivity.this, MessageID, Content, SendDate, ReadDate, Status, username, img);     
    lv.setAdapter(mAdapter);
}

AdapterMessagesII

package  MyPackageName.Adapters;
import  MyPackageName.R;
import com.pkmmte.circularimageview.CircularImageView;
import android.content.Context;
import android.graphics.Typeface;
import android.text.format.DateUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.TextView;
public class AdapterMessagesII extends BaseAdapter {
private LayoutInflater inflater;
private Typeface tf;    
private CharSequence time;
private String[] MessageID; 
private String[] Content;
private String[] SendDate;
private String[] ReadDate;
private int[] Status;   
private String Username;
private String userImage;   
public AdapterMessagesII(Context context, String[] MessageID, String[]   Content, String[] SendDate, String[] ReadDate, int[] Status, String Username, String userImage)
{
    inflater = LayoutInflater.from(context);
    this.MessageID = MessageID;
    this.Content = Content;
    this.SendDate = SendDate;
    this.ReadDate = ReadDate;
    this.Status = Status;   
    this.Username = Username;       
    this.userImage = userImage;
    tf = Typeface.createFromAsset(context.getAssets(),"fonts/MJ_DINAR ONE LIGHT.TTF");      
}
@Override
public int getCount() {
    // TODO Auto-generated method stub
    return MessageID.length;
}
@Override
public Object getItem(int position) {
    // TODO Auto-generated method stub
    return MessageID[position];
}
@Override
public long getItemId(int position) {
    // TODO Auto-generated method stub
    return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // TODO Auto-generated method stub
    ViewHolder holder = null;
    if (convertView == null)
    {
        holder = new ViewHolder();
        switch (Status[position])
        {
        case 0: //Send
            convertView = inflater.inflate(R.layout.list_messages_row_send, null);
            holder.tvSendContent = (TextView) convertView.findViewById(R.id.tv_send_message_content);
            holder.tvSendTimestamp = (TextView) convertView.findViewById(R.id.tv_send_message_timestamp);
            holder.tvSendReadDate = (TextView) convertView.findViewById(R.id.tv_send_message_read_status);              
            holder.layoutReadStatus = (LinearLayout) convertView.findViewById(R.id.layout_send_message_read_status);
            break;
        case 1: //Receive
            convertView = inflater.inflate(R.layout.list_messages_row_receive, null);
            holder.tvUsername = (TextView) convertView.findViewById(R.id.tv_receive_message_username);
            holder.tvReceiveContent = (TextView) convertView.findViewById(R.id.tv_receive_message_content);
            holder.tvReceiveTimestamp = (TextView) convertView.findViewById(R.id.tv_receive_message_timestamp);
            holder.ivReceiveUser = (CircularImageView) convertView.findViewById(R.id.iv_receive_message);
            break;
        }
        convertView.setTag(holder);
    } 
    else
    {
        holder = (ViewHolder) convertView.getTag();
    }

    switch (Status[position])
    {
    case 0: //Send
        holder.tvSendContent.setText(Content[position]);
        time = DateUtils.getRelativeTimeSpanString(Long.parseLong(SendDate[position]),
                System.currentTimeMillis(),DateUtils.SECOND_IN_MILLIS);
        holder.tvSendTimestamp.setText(time);   
        switch(ReadDate[position])
        {           
        case "x": 
            break;
        default:
            holder.layoutReadStatus.setVisibility(View.VISIBLE);
            time = DateUtils.getRelativeTimeSpanString(Long.parseLong(ReadDate[position]),
                    System.currentTimeMillis(),DateUtils.SECOND_IN_MILLIS);
            holder.tvSendReadDate.setText(time);
            break;
        }
        break;
    case 1: //Receive           
        switch(userImage)
        {
        case "x":    holder.ivReceiveUser.setImageResource(R.drawable.avatar_male_dark);
            break;
        default:    holder.ivReceiveUser.setImageBitmap(BitmapFactory.decodeFile(userImage));           
            break;
        }
        holder.tvUsername.setText(Username);
        holder.tvUsername.setTypeface(tf);
        holder.tvReceiveContent.setText(Content[position]);
        time = DateUtils.getRelativeTimeSpanString(Long.parseLong(SendDate[position]),
                System.currentTimeMillis(),DateUtils.SECOND_IN_MILLIS); 
        holder.tvReceiveTimestamp.setText(time);
        break;
    }
    return convertView;
}
static class ViewHolder
{
    TextView tvUsername;
    TextView tvReceiveContent;
    TextView tvReceiveTimestamp;
    CircularImageView ivReceiveUser;
    TextView tvSendContent;
    TextView tvSendTimestamp;
    TextView tvSendReadDate;        
    LinearLayout layoutReadStatus;
}   
}

list_messages_row_receive

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/ MyPackageName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/BackgrounColor"
android:orientation="vertical" >
<LinearLayout
    android:id="@+id/layout_receive_messages"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="5dp"
    android:layout_marginTop="5dp"
    android:orientation="horizontal"
    android:paddingLeft="5dp" >
    <LinearLayout
        android:id="@+id/qq"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:orientation="vertical" >
        <com.pkmmte.circularimageview.CircularImageView
            android:id="@+id/iv_receive_message"
            android:layout_width="45dp"
            android:layout_height="45dp"
            app:border="true"
            app:border_color="@color/LightGray"
            app:border_width="0dp" />
        <TextView
            android:id="@+id/tv_receive_message_timestamp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceSmall"
            android:textColor="@color/messagesTimestamp"
            android:textSize="8sp" />
    </LinearLayout>
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:gravity="left"
        android:orientation="vertical"
        android:paddingTop="5dp" >
        <TextView
            android:id="@+id/tv_receive_message_username"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:textColor="@color/colorPrimary"
            android:textSize="12sp" />
        <TextView
            android:id="@+id/tv_receive_message_content"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="5dp"
            android:background="@drawable/receive_message"
            android:gravity="right"
            android:lineSpacingMultiplier="1.5"
            android:maxWidth="350dp"
            android:minWidth="35dp"
            android:paddingBottom="5dp"
            android:paddingLeft="10dp"
            android:paddingRight="10dp"
            android:paddingTop="10dp"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:textColor="@color/darkGray"
            android:textSize="9sp" />
    </LinearLayout>
</LinearLayout>    
</LinearLayout>

list_messages_row_send

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layout_send_messages"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:layout_marginTop="5dp"
android:background="@color/BackgrounColor"
android:orientation="vertical" >
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="right"
    android:orientation="horizontal"
    android:paddingRight="5dp" >
    <TextView
        android:id="@+id/tv_send_message_timestamp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:layout_marginRight="5dp"
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:textColor="@color/messagesTimestamp"
        android:textSize="8sp" />
    <TextView
        android:id="@+id/tv_send_message_content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        android:background="@drawable/send_message"
        android:gravity="right"
        android:lineSpacingMultiplier="1.5"
        android:maxWidth="350dp"
        android:minWidth="35dp"
        android:paddingBottom="5dp"
        android:paddingLeft="10dp"
        android:paddingRight="10dp"
        android:paddingTop="10dp"            
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:textColor="@color/white"
        android:textSize="9sp" />        
</LinearLayout>
<LinearLayout
    android:id="@+id/layout_send_message_read_status"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginRight="5dp"
    android:layout_marginTop="2dp"
    android:gravity="right|center_vertical"
    android:paddingRight="5dp"
    android:visibility="gone"
    android:orientation="horizontal" >
    <ImageView                
        android:layout_width="12dp"
        android:layout_height="12dp"
        android:layout_marginRight="2dp"
        android:src="@drawable/icon_correct" />
    <TextView
        android:id="@+id/tv_send_message_read_status"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:textColor="@color/messagesTimestamp"
        android:textSize="8sp" />        
</LinearLayout>    
</LinearLayout>

更新:

Logcat:

08-08 16:45:39.604: I/LOG_ITEM_IMG(2872):  /storage/emulated/0/MyAppName/UserImage/010DEC12-A89A-4ACC-B6BE-7FCC677D9526.jpg
08-08 16:45:39.656: D/dalvikvm(2872): GC_FOR_ALLOC freed 1296K, 26% free 43552K/58680K, paused 4ms, total 6ms
08-08 16:45:39.660: I/dalvikvm-heap(2872): Grow heap (frag case) to 55.924MB for 14017548-byte allocation
08-08 16:45:39.664: D/dalvikvm(2872): GC_FOR_ALLOC freed 16K, 3% free 57225K/58680K, paused 7ms, total 7ms
08-08 16:45:39.736: W/Settings(2872): Setting airplane_mode_on has moved from android.provider.Settings.System to android.provider.Settings.Global, returning read-only value.
08-08 16:45:39.788: D/dalvikvm(2872): GC_FOR_ALLOC freed 17191K, 32% free 40169K/58680K, paused 6ms, total 6ms
08-08 16:45:39.800: I/dalvikvm-heap(2872): Grow heap (frag case) to 59.047MB for 20756748-byte allocation
08-08 16:45:39.808: D/dalvikvm(2872): GC_FOR_ALLOC freed 1K, 24% free 60438K/78952K, paused 6ms, total 6ms
08-08 16:45:39.860: D/dalvikvm(2872): GC_FOR_ALLOC freed 1K, 20% free 63864K/78952K, paused 4ms, total 4ms
08-08 16:45:39.860: I/dalvikvm-heap(2872): Grow heap (frag case) to 75.760MB for 14017548-byte allocation
08-08 16:45:39.868: D/dalvikvm(2872): GC_FOR_ALLOC freed <1K, 2% free 77553K/78952K, paused 8ms, total 8ms
08-08 16:45:44.380: E/InputEventReceiver(2872): Exception dispatching input event.
更新2:

在我的想法错误必须在list_messages_row_send.xmllist_messages_row_receive.xml布局或在我的适配器中使用它们。

因为当我将状态为0或1的消息传递给适配器时,当我滚动listview时没有错误。

但是当我传递一个状态为1或0(第一个状态的逆)的消息时,错误发生

将此功能添加到适配器:

private Bitmap decodeFile(File f) {
    try {
        //Decode image size
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(new FileInputStream(f),null,o);
        //The new size we want to scale to
        final int REQUIRED_SIZE=70;
        //Find the correct scale value. It should be the power of 2.
        int scale=1;
        while(o.outWidth/scale/2>=REQUIRED_SIZE && o.outHeight/scale/2>=REQUIRED_SIZE)
            scale*=2;
        //Decode with inSampleSize
        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize=scale;
        return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
    } catch (FileNotFoundException e) {}
    return null;
}

(来源:Bitmap Out Of Memory Issues)

,改变holder.ivReceiveUser.setImageBitmap(BitmapFactory.decodeFile(userImage));

holderholder.ivReceiveUser.setImageBitmap(decodeFile(new File(userImage));

当你上下滚动时,你创建的图像可能已经被垃圾收集,这意味着ListView试图重新创建这些图像,这就是为什么它崩溃了。

您需要使用LruCache或DiskLruCache缓存您的图像。

请阅读这个Android链接,它会帮助你。

http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html

public View getView(int position, View convertView,     ViewGroup parent) 
{
ViewHolder holder = null;
if (convertView == null)
{
holder = new ViewHolder();
switch (Status[position])
{
case 0: //Send
convertView = inflater.inflate(R.layout.list_messages_row_send, null);
holder.tvSendContent = (TextView) convertView.findViewById(R.id.tv_send_message_content);
holder.tvSendTimestamp = (TextView) convertView.findViewById(R.id.tv_send_message_timestamp);
holder.tvSendReadDate = (TextView) convertView.findViewById(R.id.tv_send_message_read_status);              
holder.layoutReadStatus = (LinearLayout) convertView.findViewById(R.id.layout_send_message_read_status);
break;
case 1: //Receive
convertView = inflater.inflate(R.layout.list_messages_row_receive, null);
holder.tvUsername = (TextView) convertView.findViewById(R.id.tv_receive_message_username);
holder.tvReceiveContent = (TextView) convertView.findViewById(R.id.tv_receive_message_content);
holder.tvReceiveTimestamp = (TextView) convertView.findViewById(R.id.tv_receive_message_timestamp);
holder.ivReceiveUser = (CircularImageView) convertView.findViewById(R.id.iv_receive_message);
break;
}

convertView.setTag(持有人);}其他的{holder = (ViewHolder) convertview . getag ();}开关(状态(位置)){case 0://发送holder.tvSendContent.setText(内容(位置));time = DateUtils.getRelativeTimeSpanString(Long.parseLong(SendDate[position])),System.currentTimeMillis (), DateUtils.SECOND_IN_MILLIS);
holder.tvSendTimestamp.setText(时间);if (ReadDate[position] != null){holder.layoutReadStatus.setVisibility (View.VISIBLE);time = DateUtils.getRelativeTimeSpanString(Long.parseLong(ReadDate[position])),System.currentTimeMillis (), DateUtils.SECOND_IN_MILLIS);holder.tvSendReadDate.setText(时间);}//结束if打破;案例1://接收
if (userImage != null){ holder.ivReceiveUser.setImageResource (R.drawable.avatar_male_dark);}其他{holder.ivReceiveUser.setImageBitmap (BitmapFactory.decodeFile (userImage));}holder.tvUsername.setText(用户名);holder.tvUsername.setTypeface (tf);holder.tvReceiveContent.setText(内容(位置));time = DateUtils.getRelativeTimeSpanString(Long.parseLong(SendDate[position])),System.currentTimeMillis (), DateUtils.SECOND_IN_MILLIS);holder.tvReceiveTimestamp.setText(时间);打破;}//结束开关(Status[position])

return convertView;
}

为了简单明了,我建议如下创建2个AdapterClasses;AdapterClass1AdapterClass2类SwitchView扩展AsyncTask{@overrideprotected void doInBackground(Integer…params){int [0];开关(whichView){例0://加载适配器类打破;案例1;//加载适配器类打破;}//结束开关}//结束doinbackgroundonPostExecute(){//取消ProgressDialog}//结束SwitchView

最新更新