这个程序主要开辟子线程,从服务器获取图片的url,然后利用url从网络下载图片的。运行时,不知何种原因,莫名的死掉,只能打印出一堆GC信息
检查你用的这台手机,后台Log开关是否打开了。 百度一下
请提供 源代码 或出错的 LOG,否则别人没有办法帮到你。
最简单的方法,多增加一些 LOG,看看执行到哪里时出现问题的。
然后,再分析代码找原因吧。
package com.fangle.epark.business.event.ui;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.fangle.android.uicomponent.DirUtil;
import com.fangle.android.uicomponent.ToastUtil;
import com.fangle.comutil.HttpUtil;
import com.fangle.comutil.LogManager;
import com.fangle.epark.EParkApplication;
import com.fangle.epark.R;
import com.fangle.epark.Constant.Constant;
import com.fangle.epark.business.event.logic.EventListLogic;
import com.fangle.epark.business.event.po.EventInfoItemPo;
import com.fangle.epark.business.event.po.EventInfosPo;
import com.fangle.epark.business.event.vo.EventSearchReqVo;
import com.fangle.epark.business.user.ui.LoginActivity;
import com.fangle.epark.jsonvo.event.EventInfosVo;
public class EventActivity extends Activity {
private static final LogManager LOGGER = new LogManager("EventActivity");
// ListView的Adapter
private EventInfoAdapter eventInfoAdapter;
private ListView lv;
private Button bt;
private ProgressBar pg;
// ListView底部View
private View moreView;
// 设置一个最大的数据条数,超过即不再加载
private int MaxDateNum = 100; // 设置最大数据条数
private LinearLayout llyMore,llyBack;
private LinearLayout llyLoad;
private TextView tvLoadNodify;
private ProgressBar progressBar;
private EventListLogic eventListLogic;
private EventInfosPo eventInfosPo = new EventInfosPo();
private EventInfosVo eventInfosVo = new EventInfosVo();
private static final int CHECK_EVENT_FAIL = 70;
private static final int CHECK_EVENT_OK = 71;
private static final int CHECK_MORE_EVENT_OK = 72;
private static final int ANALYSIS_EVENT_ERROR = 73;
private static final int GET_BITMAP_OK = 74;
private static final int NO_EVENTS = 75;
private static final int NO_NORE_EVENTS = 76;
private static final int TOKEN_ERROR = 77;
//private boolean isGetMyEvent = false; //是否查看自己发布的事件,默认为否
private boolean isGetByStyle = false;
private EventSearchReqVo searchVo;
private int screenWidth,screenHeight;
private final String imagePath=DirUtil.TEMP_PATH + "/"+ "eventPreviewImage";
private Context context;
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case CHECK_EVENT_FAIL:
showView("netError");
break;
case NO_EVENTS:
showView("emptyData");
break;
case NO_NORE_EVENTS:
showView("noMoreData");
break;
case CHECK_EVENT_OK:
eventInfosPo.clear();
if(eventInfosVo.events!=null){
eventListLogic.toEventListPo(eventInfosPo, eventInfosVo); // 将Vo转换成Po
}
if(isGetByStyle){
eventInfoAdapter.notifyDataSetChanged();
}
lv.addFooterView(moreView);
bt.setVisibility(View.VISIBLE);
pg.setVisibility(View.GONE);
showView("eventList");
getImage(); // 解析图片
break;
case CHECK_MORE_EVENT_OK:
if(eventInfosVo.events!=null){
eventListLogic.toEventListPo(eventInfosPo, eventInfosVo); // 将Vo转换成Po
}
bt.setVisibility(View.VISIBLE);
pg.setVisibility(View.GONE);
eventInfoAdapter.notifyDataSetChanged();// 通知listView刷新数据
showView("eventList");
getImage(); // 解析图片
break;
case ANALYSIS_EVENT_ERROR:
ToastUtil.showToastShortTime(context, "获取照片报错!");
break;
case GET_BITMAP_OK:
eventInfoAdapter.notifyDataSetChanged();// 图片解析成功,通知listView刷新数据
break;
case TOKEN_ERROR:
ToastUtil.showToastShortTime(context, "token失效,请重新登录");
Intent in=new Intent(context,LoginActivity.class);
startActivity(in);
finish();
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.event);
EParkApplication.addActivity(this);
System.gc();
context=this;
initView();
// 从网络初始化数据
searchVo = new EventSearchReqVo();
showView("loading"); // 显示"加载中..."
getDataFromServer(false);
}
@Override
protected void onDestroy()
{
EParkApplication.removeActivity(this);
//在activity退出时,将bitmap回收
for(EventInfoItemPo po: eventInfosPo.eventList){
for(int i=0;i<po.getEventViews().length;i++){
if(po.getEventViews()[i]!=null&&!po.getEventViews()[i].isRecycled()){
po.getEventViews()[i].recycle();
}
}
}
System.gc();
super.onDestroy();
}
private void initView(){
screenWidth = getWindowManager().getDefaultDisplay().getWidth();
screenHeight = getWindowManager().getDefaultDisplay().getHeight();
eventListLogic = new EventListLogic(context);
lv = (ListView) findViewById(R.id.main_event_listview);
// 实例化底部布局
LayoutInflater inflater = LayoutInflater.from(this);
moreView = inflater.inflate(R.layout.more_data, null);
bt = (Button) moreView.findViewById(R.id.bt_load);
pg = (ProgressBar) moreView.findViewById(R.id.pg);
// 实例化eventInfoAdapter
eventInfoAdapter = new EventInfoAdapter(this,
R.layout.event_item, eventInfosPo.getEventList());
// 加上底部View,注意要放在setAdapter方法前
lv.addFooterView(moreView);
lv.setAdapter(eventInfoAdapter);
//moreView.setVisibility(View.GONE);
bt.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
pg.setVisibility(View.VISIBLE);// 将进度条可见
bt.setVisibility(View.GONE);// 按钮不可见
loadMoreDateFromServer();// 从网络加载更多数据
}
});
llyLoad = (LinearLayout) findViewById(R.id.event_lly_load);
tvLoadNodify = (TextView) findViewById(R.id.tv_event_load_nodify);
progressBar = (ProgressBar)findViewById(R.id.event_progressBar);
llyLoad.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
showView("loading"); // 显示"加载中..."
getDataFromServer(false); //当网络出错,或没获取到数据时,单击此刷新
}
});
llyMore = (LinearLayout) findViewById(R.id.llayout_more);
llyMore.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
showPopupMenu(); //显示下拉菜单
}
});
llyBack = (LinearLayout)findViewById(R.id.event_llayout_back);
llyBack.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
EventActivity.this.finish();
}
});
}
/**
* 扩展功能
*/
private void showPopupMenu(){
final String[] mItems = getResources().getStringArray(R.array.get_event_style);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("");
builder.setItems(mItems, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
switch(which){
case 0: //刷新列表
isGetByStyle = true;
searchVo.setPageNo(1);
showView("loading"); // 显示"加载中..."
getDataFromServer(false);// 从网络加载数据
dialog.dismiss();
break;
case 1: //发布事件
Intent intent = new Intent(EventActivity.this,
EventIssueActivity.class);
startActivity(intent);
dialog.dismiss();
break;
case 2: //查询我发布的事件
isGetByStyle = true;
searchVo.setIsMy(1);
searchVo.setPageNo(1);
getDataFromServer(false);
break;
case 3: //查询所有人发布的事件
isGetByStyle = true;
searchVo.setIsMy(0);
searchVo.setPageNo(1);
getDataFromServer(false);
break;
}
}
});
builder.create().show();
}
/**
* 从网络加载更多数据
*/
private void loadMoreDateFromServer() {
int pageNo = searchVo.getPageNo() + 1;
searchVo.setPageNo(pageNo);
getDataFromServer(true);
}
/**
* 从网络获取数据
*/
public void getDataFromServer(final boolean isMore) {
new Thread() {
@Override
public void run() {
EventInfosVo eventDatatListModel = (EventInfosVo) eventListLogic
.getEventList(searchVo);
if (isMore == false) { // 初次获取
if (eventDatatListModel == null) {
//LOGGER.debug("查看事件失败!!");
handler.sendEmptyMessage(CHECK_EVENT_FAIL);
} else if (eventDatatListModel.ret == Constant.RET_OK) {
eventInfosVo = eventDatatListModel;
if (Integer.parseInt(eventDatatListModel.currentCount) > 0) {
handler.sendEmptyMessage(CHECK_EVENT_OK);
} else {
handler.sendEmptyMessage(NO_EVENTS); // 查询的事件不存在
//LOGGER.debug("----------nu events-----");
}
}else if(eventDatatListModel.ret == Constant.TOKEN_ERROR){
handler.sendEmptyMessage(TOKEN_ERROR);
}
} else { // 获取更多
if (eventDatatListModel != null
&& eventDatatListModel.ret == Constant.RET_OK) {
eventInfosVo = eventDatatListModel;
if (Integer.parseInt(eventDatatListModel.currentCount) > 0) {
handler.sendEmptyMessage(CHECK_MORE_EVENT_OK);
} else {
handler.sendEmptyMessage(NO_NORE_EVENTS); // 没有更多的数据了
}
}else{
handler.sendEmptyMessage(NO_NORE_EVENTS); // 没有更多的数据了
}
}
}
}.start();
}
private void getImage() {
new Thread(){
@Override
public void run() {
for(int i=0;i<eventInfosPo.eventList.size();i++){
EventInfoItemPo item=eventInfosPo.eventList.get(i);
if(item.isDownImg()==false){
String urls[]=item.getImageUrls();
if(urls!=null&&urls.length>0){
String files[]=new String[urls.length];
Bitmap[] bitmaps = new Bitmap[urls.length];
for(int imageIndex=0;imageIndex<item.getImageUrls().length;imageIndex++){
files[imageIndex]=imagePath+item.getId()+imageIndex;
if(HttpUtil.getBitmap(urls[imageIndex],files[imageIndex],screenWidth,screenHeight)!=null){
bitmaps[imageIndex]=HttpUtil.getBitmap(urls[imageIndex],files[imageIndex],screenWidth,screenHeight);
}
}
item.setImageFiles(files);
item.setEventViews(bitmaps);
}
item.setDownImg(true); //设置这个事件已经完成照片解析
handler.sendEmptyMessage(GET_BITMAP_OK);
}
}
}
}.start();
}
/**
*
* @param flag
* loading:显示“加载中..", eventList:显示"事件列表",
* empty:显示空数据, netError:显示网络异常
* @param isLoadMore
* show==parkList时才有效果,表示是否在加载更多中...
*/
private void showView(String show){
if(show.equals("loading")){
lv.setVisibility(View.GONE);
llyLoad.setVisibility(View.VISIBLE);
llyLoad.setClickable(false);
progressBar.setVisibility(View.VISIBLE);
tvLoadNodify.setText("加载中...");
}else if(show.equals("netError")){
lv.setVisibility(View.GONE);
llyLoad.setVisibility(View.VISIBLE);
llyLoad.setClickable(true);
progressBar.setVisibility(View.GONE);
tvLoadNodify.setText("网络异常,请点击重试!");
}else if(show.equals("emptyData")){
lv.setVisibility(View.GONE);
llyLoad.setVisibility(View.VISIBLE);
llyLoad.setClickable(true);
progressBar.setVisibility(View.GONE);
tvLoadNodify.setText("没有相关事件,请点击重试!");
}else if(show.equals("eventList")){
lv.setVisibility(View.VISIBLE);
llyLoad.setVisibility(View.GONE);
}else if(show.equals("noMoreData")){
lv.setVisibility(View.VISIBLE);
llyLoad.setVisibility(View.GONE);
lv.removeFooterView(moreView);
bt.setVisibility(View.VISIBLE);
pg.setVisibility(View.GONE);
ToastUtil.showToastShortTime(context, "没有更多的事件了");
}
}
}
这个是出错那个类的代码,以前用另一个手机调试的时候没出现过类似问题,现在换了个稍微低点的手机,就出现这问题了。而且看不到debug信心啊,logcat就打印一堆GC_EXPLICIT freed 182K, 9% free 12147K/13255K, paused 3ms+4ms, total 49ms然后就什么都没了
从你的描述看,应该是低配置机器的java虚拟机heapsize设置得比较小造成的。
你可以参考下面这个链接,修改一下你的Manifest文件试试。
如果低端机的本身限制了Heapsize,那就要考虑优化你的app了,得减小内存消耗才行。
http://zhidao.baidu.com/link?url=WOWlW4BG3tfClk8yk43luISD6Qaw73SAjDGZ3FzLMfd-vKlvnXIhCU21SJ-bZWRzI9qQaFlAfLkAXPuJf83B3K
CaptainJno 的解答很好,虽然看到时已经是几天后的事情了。这个问题当时确实很让我头大,最终发现就是log开关没打开,我以前没碰到过这样的问题,挺郁闷。我把相关的解决办法也转过来,如果有遇到类似问题的同仁,可以参考