我正在开发自己的消息应用程序,用于向/从服务器发送和接收消息。
我正在使用名为状态的整数数组,表示邮件是传出或传入。
当我在 MessageActivity 中的下方评论时,listview会向我显示一些消息,但是当我向下滚动时,我的应用程序崩溃,我得到编舞错误。
holder.ivReceiveUser.setImageBitmap(BitmapFactory.decodeFile(userImage));
另外,当我不在上面评论时,我得到 BitmapFactory 错误。 (我确定imagePath是真的,因为我在其他活动中使用它)
任何建议都将受到赞赏......
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.xml 和 list_messages_row_receive.xml 布局中,或者在我的适配器中使用它们。
因为当我只将状态为0或1的消息传递给适配器时,滚动列表视图时没有错误。
但是当我传递一条状态为1或0(第一个状态的反转)的消息时,就会发生错误。
答案 0 :(得分:1)
将此功能添加到适配器:
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));
我希望有效
答案 1 :(得分:1)
当您向上和向下滚动时,您创建的图像可能已被垃圾收集,这意味着ListView正在尝试再次重新创建这些图像,这就是它崩溃的原因。
您需要使用Eru 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.getTag();
}
开关(状态[位置])
{
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(时间);
}// 万一
打破;
案例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(时间);
打破;
} //结束开关(状态[位置])
return convertView;
}
我将推荐简化和Clarit,创建2个AdapterClasses,如下所示; AdapterClass1 AdapterClass2 class SwitchView扩展了AsyncTask { @override protected void doInBackground(Integer ... params) { int whichView = params [0]; 开关(whichView) { 案例0: //加载AdapterClass 1 打破; 情况1; //加载AdapterClass 2 打破; } //结束开关 } //结束doInBackgroud protected void onPostExecute() { //关闭ProgressDialog } } //结束SwitchView