让Android融入我的生活!
前段时间一直忙,项目赶时间上线,时间紧,任务重,天天加班,还搞了三个通宵,最终按照领导要求,保证项目按时上线,现在轻松
下来了,一整天没事干,闲暇之余,想对自己开发的工作总结一下,感觉颇有收获,总结如下,给大家分享一下,希望能给大家带来些
许帮助!欢迎评论,欢迎分享,欢迎收藏!
1:项目开发前,我们一定要全面了解项目中所有的界面需求,实现界面都需要用到哪些组件,比如现在的Android应用中特别流行圆形
Icon、Listview上滑加载、下拉刷新、百度定位、各种分享、Listview动态加载网络图片等等所有的需求,在应用开发前,一定要设计好所有
UI控件,保证后期项目开发的流畅性
2:圆形图片建议大家使用universal-image-loader库,不要用CircularImage、RoundedImageView等自定义控件,因为这些自定义控件
在加载分辨率特别小的图片时,会出现黑边框,且为必现,此问题测试时会提出Bug,无法解决,如果后期才替换那将会导致很大的工作量
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
loginIcon=(ImageView) view.findViewById(R.id.login_user_icon);
loginUserName=(TextView) view.findViewById(R.id.login_user_name);
redPoint=(TextView) view.findViewById(R.id.notify_red_point);
options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.user)
.showImageForEmptyUri(R.drawable.user)
.showImageOnFail(R.drawable.user).cacheInMemory(true)
.cacheOnDisk(true).considerExifParams(true)
.displayer(new RoundedBitmapDisplayer(150)).build();
setRedPoint();
}
@Override
public void onResume() {
// TODO Auto-generated method stub
super.onResume();
setRedPoint();
ImageLoader.getInstance().displayImage(BaseApplication.getApp().mUser.getHeadIcon(),
loginIcon, options, null);
loginUserName.setText(BaseApplication.getApp().mUser.getName());
}
3:全局注入异常处理类CrashHandler,在自己的Application中启动即可,此异常处理类非常有用,后期会出现一些莫名期妙的Bug,且
为偶现,光靠测试很难发现导致Bug的原因,有些异常处理类记录日志,会极大的节省我们查找Bug原因的时间,因为日志是时时记录的,只有
出现Bug,就会有日志记录,非常方便
public class CrashHandler implements UncaughtExceptionHandler {
/** Debug Log Tag */
public static final String TAG = "CrashHandler";
/** 是否开启日志输出, 在Debug状态下开启, 在Release状态下关闭以提升程序性能 */
public static final boolean DEBUG = true;
/** CrashHandler实例 */
private static CrashHandler INSTANCE;
/** 程序的Context对象 */
private Context mContext;
/** 用来存储设备信息和异常信息 */
private Map
infos = new HashMap
();
/** 用于格式化日期,作为日志文件名的一部分 */
private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
/** 系统默认的UncaughtException处理类 */
private Thread.UncaughtExceptionHandler mDefaultHandler;
/** 使用Properties来保存设备的信息和错误堆栈信息 */
private Properties mDeviceCrashInfo = new Properties();
private static final String VERSION_NAME = "versionName";
private static final String VERSION_CODE = "versionCode";
private static final String STACK_TRACE = "STACK_TRACE";
/** 错误报告文件的扩展名 */
private static final String CRASH_REPORTER_EXTENSION = ".cr";
/** 错误报告的详细信息 */
private JSONObject report;
/** 保证只有一个CrashHandler实例 */
private CrashHandler() {
}
/** 获取CrashHandler实例 ,单例模式 */
public static CrashHandler getInstance() {
if (INSTANCE == null)
INSTANCE = new CrashHandler();
return INSTANCE;
}
/**
* 初始化,注册Context对象, 获取系统默认的UncaughtException处理器, 设置该CrashHandler为程序的默认处理器
*
* @param ctx
*/
public void init(Context ctx) {
mContext = ctx;
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(this);
}
/**
* 当UncaughtException发生时会转入该函数来处理
*/
@Override
public void uncaughtException(Thread thread, Throwable ex) {
ex.printStackTrace();
// 收集设备信息
collectCrashDeviceInfo(mContext);
// 保存错误报告文件
saveCrashInfoToFile(ex);
//将错误信息发送的服务器
ThreadPool.getInstance().addTask(crashThread);
new Thread() {
@Override
public void run() {
// Toast 显示需要出现在一个线程的消息队列中
Looper.prepare();
Toast.makeText(mContext, "程序出错,即将退出", Toast.LENGTH_LONG).show();
Looper.loop();
}
}.start();
// Sleep一会后结束程序
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
MyActivityManager.getInstance().popAllActivity();
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(10);
}
/**
* 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成. 开发者可以根据自己的情况来自定义异常处理逻辑
*
* @param ex
* @return true:如果处理了该异常信息;否则返回false
*/
private boolean handleException(Throwable ex) {
if (ex == null) {
return true;
}
final String msg = ex.getLocalizedMessage();
// 使用Toast来显示异常信息
new Thread() {
@Override
public void run() {
// Toast 显示需要出现在一个线程的消息队列中
Looper.prepare();
Toast.makeText(mContext, "程序出错啦:" + msg, Toast.LENGTH_LONG)
.show();
Looper.loop();
}
}.start();
// 收集设备信息
collectCrashDeviceInfo(mContext);
// 保存错误报告文件
saveCrashInfoToFile(ex);
// 发送错误报告到服务器
sendCrashReportsToServer(mContext);
return true;
}
/**
* 保存错误信息到文件中
*
* @param ex
* @return
*/
private String saveCrashInfoToFile(Throwable ex) {
report=new JSONObject();
String result = getCrashInfo(ex);
StringBuffer sb = new StringBuffer();
mDeviceCrashInfo.put(STACK_TRACE, result);
mDeviceCrashInfo.put("TIME", System.currentTimeMillis()+"");
Set
> set=mDeviceCrashInfo.entrySet();
for(Entry
entry:set){ sb.append(entry.getKey().toString()).append("==="); sb.append(entry.getValue()); sb.append("\n"); try { report.put(entry.getKey().toString(), entry.getValue()); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } } // 保存文件 try { String path=StorageUtils.getInstance(mContext).getLogDir().getPath(); String fileName = "crash-" + Common.getCurrentForFileName() + CRASH_REPORTER_EXTENSION; FileOutputStream fos = new FileOutputStream(path +File.separator+ fileName); fos.write(sb.toString().getBytes()); fos.flush(); fos.close(); return fileName; } catch (Exception e) { e.printStackTrace(); } return null; } }