2 stone 2323 stone_2323 于 2014.12.01 17:43 提问

android程序,在运行时莫名的死掉,只打印一堆GC信息,其他调试信息看不到

这个程序主要开辟子线程,从服务器获取图片的url,然后利用url从网络下载图片的。运行时,不知何种原因,莫名的死掉,只能打印出一堆GC信息

6个回答

qq787068730
qq787068730   2014.12.09 16:17
已采纳

检查你用的这台手机,后台Log开关是否打开了。 百度一下

codehat
codehat   2014.12.04 19:38

从你的描述看,应该是低配置机器的java虚拟机heapsize设置得比较小造成的。
你可以参考下面这个链接,修改一下你的Manifest文件试试。
如果低端机的本身限制了Heapsize,那就要考虑优化你的app了,得减小内存消耗才行。
http://zhidao.baidu.com/link?url=WOWlW4BG3tfClk8yk43luISD6Qaw73SAjDGZ3FzLMfd-vKlvnXIhCU21SJ-bZWRzI9qQaFlAfLkAXPuJf83B3K

91program
91program   Ds   Rxr 2014.12.01 18:11

请提供 源代码 或出错的 LOG,否则别人没有办法帮到你。

91program
91program   Ds   Rxr 2014.12.01 18:12

最简单的方法,多增加一些 LOG,看看执行到哪里时出现问题的。
然后,再分析代码找原因吧。

stone_2323
stone_2323   2014.12.02 08:42

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然后就什么都没了

stone_2323
stone_2323   2014.12.10 16:30
                CaptainJno 的解答很好,虽然看到时已经是几天后的事情了。这个问题当时确实很让我头大,最终发现就是log开关没打开,我以前没碰到过这样的问题,挺郁闷。我把相关的解决办法也转过来,如果有遇到类似问题的同仁,可以参考
Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!