天天看点

Android项目开发前准备工作(一)

     让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; } } 
      
     
    
   
  
           

继续阅读