- 浏览: 636707 次
文章分类
最新评论
-
涛声依旧是:
怎么提示掉线,怎么才能在线
基于Tomcat7、Java、WebSocket的服务器推送聊天室 -
dcode:
楼主写的不错,正好遇到点问题,看着你的文章解决了,感谢分享。。 ...
在 Visual Studio 2010 中配置SharpPcap
Android tree应用框架
简介
一个好的Android应用开发框架,可以加快Android开发速度,今天笔记基于许多开源项目自写了一款Android应用框架。
内容
框架包括:界面管理(Activity管理)、数据库操作(orm框架、加密等)、http交互、缓存管理、下载管理、路径管理、日志输出、网络管理、系统命令、加解密、stl容器、任务管理、奔溃管理、存储管理、其它辅助管理…。
解决思路如下:
界面管理:使用Stack记录Activity的运行轨迹,并在每个Activity添加一个广播处理自定义事件。
private static Stack<Activity> mActivityStack;//进行Activity运行记录数据库管理:对数据库的操作要求orm框架、加解密等,采用的是greendao和sqlcrypt开源项目解决。
http交互:实现http交互方式有同步、异步操作。采用的是android-async-http开源项目解决。
缓存管理:实现缓存方式有内存缓存、磁盘缓存。其中内存缓存只针对图片处理,磁盘缓存是针对某目录,实现的方式有:先进先出、最大量、使用频率等。
下载管理:下载管理方式有多线程下载、单线程下载。
路径管理:简单的说就是对程序的目录管理,分图片、视频、音频、缓存目录等。
日志输出:基于Log的管理(分调式、发布模式和文件输出、log输出)。
网络管理:2G、3G、4G等联网方式不同的管理和监听。
系统命令:直接命令运行。
加解密:aes、base64、des、md5等加密方式。
stl容器:重写stl部分容器。
任务管理:基于AsyncTask任务的管理。
奔溃管理:捕捉奔溃信息,并提供发送接口。采用的是acra方法解决。
存储管理:主要是SharedPreferences和Properties的管理。
其它辅助管理:版本、内存、手机格式、字符串操作……等等。
项目如图:
效果如图:
+
相关测试代码:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.test_tree); TFilePathManager.getInstance().initConfig(null); // 默认目录(下载�?图片、视频�?缓存等目�? // 优先考虑内存条,其次手机内存�? } public void onClickTestPath(View view) { // 测试路径 TFilePathManager.getInstance().initConfig( Environment.getExternalStorageDirectory().getPath() + File.pathSeparator + "test"); // 程序目录里面分了图片、缓存区、下载图、音频区、视频区 TFilePathManager.getInstance().getAppPath(); TFilePathManager.getInstance().getAudioPath(); TFilePathManager.getInstance().getCachePath(); TFilePathManager.getInstance().getDownloadPath(); TFilePathManager.getInstance().getImagePath(); } public void onClickTestLog(View view) { // 测试日志 TLog.enablePrintToFileLogger(true); for (int i = 0; i < 100; i++) TLog.i(TAG, "123456" + i); // TLog.release(); //关闭程序可释�? // 日志是放在程序目录下 // TLog.enableIgnoreAll(enable); // TLog.enableIgnoreWarn(enable); } public void onClickTestTActivity(View view) { // 测试TActivity Intent intent = new Intent(); intent.setClass(this, TestTActivity.class); startActivity(intent); } public void onClickTestHttp1(View view) { // 测试Http1 Intent intent = new Intent(); intent.setClass(this, TestHttp1.class); startActivity(intent); } public void onClickTestHttp2(View view) { // 测试Http2 Intent intent = new Intent(); intent.setClass(this, TestHttp2.class); startActivity(intent); } public void onClickTestThreadsdown(View view) { // 测试多线程下载 Intent intent = new Intent(); intent.setClass(this, TestDowns.class); startActivity(intent); } public void onClickTestCrash(View view) { // 崩溃 int result = 1 / 0; } public void onClickTestSqlEncrypt(View view) { // 测试sql加密 Intent intent = new Intent(); intent.setClass(this, TestSqlEncrypt.class); startActivity(intent); } public void onClickTestDAO(View view) { // 测试orm数据库 Intent intent = new Intent(); intent.setClass(this, TestDAO.class); startActivity(intent); } public void onClickTestDB(View view) { // 测试Think数据库 Intent intent = new Intent(); intent.setClass(this, TestDB.class); startActivity(intent); } public void onClickTestCache(View view) { // 测试缓存 Intent intent = new Intent(); intent.setClass(this, TestCache.class); startActivity(intent); } public void onClickTConfig(View view) { // 测试配置信息 TPreferenceConfig.getInstance().initConfig(this); TPropertiesConfig.getInstance().initConfig(this); TIConfig iConfig = TPreferenceConfig.getInstance(); iConfig.setBoolean("123", true); boolean result = iConfig.getBoolean("123", false); iConfig = TPropertiesConfig.getInstance(); iConfig.setBoolean("1234", true); result = iConfig.getBoolean("1234", false); } public void onClickEncryption(View view) { // 测试加密 String src = "banketree@qq.com"; String encrypted = ""; String key = "banketree"; try { encrypted = TAes.encrypt(key, src); String tempString = TAes.decrypt(key, encrypted); encrypted = TBase64.encode(src.getBytes()); tempString = TBase64.decode(encrypted).toString(); encrypted = TDes.encrypt(key, src); tempString = TDes.decrypt(key, encrypted); TLog.i(this, tempString); } catch (Exception e) { e.printStackTrace(); } } public void onClickZip(View view) { // 测试解压缩 try { TCompressUtils.compressJar(""); TCompressUtils.compressZip(""); TCompressUtils.uncompressJar(""); TCompressUtils.uncompressZip(""); } catch (Exception e) { e.printStackTrace(); } }
奔溃处理回调:
@Override public void onAppCrash(String crashFile) { TLog.d(TAG, "Creating Dialog for " + crashFile); Intent dialogIntent = new Intent(this, TestCrash.class); dialogIntent.putExtra(TCrash.EXTRA_REPORT_FILE_NAME, crashFile); dialogIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(dialogIntent); }
mMemoryCacheSize = 2 * 1024 * 1024;// 2M mDiscCacheSize = 2 * 1024 * 1024;// 2M mDiscCacheFileCount = 100;// 一百个文件 mMemoryCache = TCacheManager.createLruMemoryCache(mMemoryCacheSize); try { mDiscCache1 = TCacheManager.createReserveDiscCache(TFilePathManager .getInstance().getCachePath(), "test"); } catch (Exception e) { e.printStackTrace(); } try { mDiscCache2 = TCacheManager.createFileCountLimitedDiscCache( mDiscCacheFileCount, TFilePathManager.getInstance() .getCachePath()); } catch (Exception e) { e.printStackTrace(); }
try { Drawable demo = getResources().getDrawable(R.drawable.ic_launcher); Bitmap bitmap = ((BitmapDrawable) demo).getBitmap(); if (arg0 == mTest1Button) { mMemoryCache.put("123", bitmap); mMemoryCache.put("1234", bitmap); mMemoryCache.get("123"); mMemoryCache.get("1234"); } else if (arg0 == mTest2Button) { mDiscCache1.put("123", mContext.getCacheDir()); mDiscCache1.get("123"); } else if (arg0 == mTest3Button) { mDiscCache2.put("123", mContext.getCacheDir()); mDiscCache2.get("123"); } } catch (Exception e) { makeText(e.getMessage()); }
Activity之间的通信:
@Override public void onClick(View arg0) { if (testComparatorButton == arg0) { Log.i("", ""); UIBroadcast.sentEvent(mContext, 1001, 1002, ""); } } @Override public void processEvent(Intent intent) { super.processEvent(intent); int mainEvent = intent.getIntExtra(UIBroadcast.MAINEVENT, -1); // 主事�? int subEvent = intent.getIntExtra(UIBroadcast.EVENT, -1);// 次事�? makeText("哈哈触发�?" + mainEvent + subEvent);// 每个Activity可接收广�? }
Http同步异步请求:
if (view == mCancelButton) { mTAsyncHttpClient.cancelRequests(this, true); mTAsyncHttpClient.cancelAllRequests(true); } else if (view == mGetButton) { url = "https://httpbin.org/get"; mTAsyncHttpClient.get(url, new AsyncHttpResponseHandler() { @Override public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) { debugHeaders(headers); debugStatusCode(statusCode); debugResponse(new String(responseBody)); } @Override public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) { debugHeaders(headers); debugStatusCode(statusCode); if (responseBody != null) { debugResponse(new String(responseBody)); } TLog.e(this, error.getMessage()); } @Override public void onProgress(int bytesWritten, int totalSize) { super.onProgress(bytesWritten, totalSize); } @Override public void onRetry(int retryNo) { makeText(String.format("Request is retried, retry no. %d", retryNo)); } }); } else if (view == mPostButton) { url = "http://httpbin.org/post"; mTAsyncHttpClient.post(mContext, url, getRequestHeaders(), getRequestEntity(), null, new AsyncHttpResponseHandler() { @Override public void onStart() { } @Override public void onSuccess(int statusCode, Header[] headers, byte[] response) { debugHeaders(headers); debugStatusCode(statusCode); debugResponse(new String(response)); } @Override public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) { debugHeaders(headers); debugStatusCode(statusCode); debugThrowable(e); if (errorResponse != null) { debugResponse(new String(errorResponse)); } } }); } else if (view == mPutButton) { url = "http://httpbin.org/put"; mTAsyncHttpClient.put(this, url, getRequestHeaders(), getRequestEntity(), null, new AsyncHttpResponseHandler() { @Override public void onStart() { } @Override public void onSuccess(int statusCode, Header[] headers, byte[] response) { debugHeaders(headers); debugStatusCode(statusCode); debugResponse(new String(response)); } @Override public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) { debugHeaders(headers); debugStatusCode(statusCode); debugThrowable(e); if (errorResponse != null) { debugResponse(new String(errorResponse)); } } }); } else if (view == mDeleteButton) { url = "http://httpbin.org/delete"; mTAsyncHttpClient.delete(this, url, getRequestHeaders(), null, new AsyncHttpResponseHandler() { @Override public void onStart() { } @Override public void onSuccess(int statusCode, Header[] headers, byte[] response) { debugHeaders(headers); debugStatusCode(statusCode); debugResponse(new String(response)); } @Override public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) { debugHeaders(headers); debugStatusCode(statusCode); debugThrowable(e); if (errorResponse != null) { debugResponse(new String(errorResponse)); } } }); } else if (view == mFileButton) { url = "https://httpbin.org/robots.txt"; mTAsyncHttpClient.get(this, url, getRequestHeaders(), null, new FileAsyncHttpResponseHandler(this) { @Override public void onStart() { } @Override public void onSuccess(int statusCode, Header[] headers, File response) { debugHeaders(headers); debugStatusCode(statusCode); debugFile(response); } @Override public void onFailure(int statusCode, Header[] headers, Throwable throwable, File file) { debugHeaders(headers); debugStatusCode(statusCode); debugThrowable(throwable); debugFile(file); } private void debugFile(File file) { if (file == null || !file.exists()) { debugResponse("Response is null"); return; } try { debugResponse(file.getAbsolutePath() + "\r\n\r\n" + TFileUtils.getStringFromFile(file)); } catch (Throwable t) { TLog.e(TAG, "Cannot debug file contents" + t.getMessage()); } if (!deleteTargetFile()) { TLog.d(TAG, "Could not delete response file " + file.getAbsolutePath()); } } }); } else if (view == mGZipButton) { url = "http://httpbin.org/gzip"; mTAsyncHttpClient.get(this, url, null, null, new BaseJsonHttpResponseHandler<SampleJSON>() { @Override public void onStart() { } @Override public void onSuccess(int statusCode, Header[] headers, String rawJsonResponse, SampleJSON response) { debugHeaders(headers); debugStatusCode(statusCode); if (response != null) { debugResponse(rawJsonResponse); } } @Override public void onFailure(int statusCode, Header[] headers, Throwable throwable, String rawJsonData, SampleJSON errorResponse) { debugHeaders(headers); debugStatusCode(statusCode); debugThrowable(throwable); if (errorResponse != null) { debugResponse(rawJsonData); } } @Override protected SampleJSON parseResponse(String rawJsonData, boolean isFailure) throws Throwable { return null; // return new ObjectMapper().readValues( // new JsonFactory().createParser(rawJsonData), // SampleJSON.class).next(); } }); } else if (view == mRedirect302Button) { url = "http://httpbin.org/redirect/6"; HttpClient client = mTAsyncHttpClient.getHttpClient(); if (client instanceof DefaultHttpClient) { // enableRedirects/enableRelativeRedirects/enableCircularRedirects mTAsyncHttpClient.setEnableRedirects(true, true, true); } mTAsyncHttpClient.get(url, new AsyncHttpResponseHandler() { @Override public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) { debugHeaders(headers); debugStatusCode(statusCode); debugResponse(new String(responseBody)); } @Override public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) { debugHeaders(headers); debugStatusCode(statusCode); if (responseBody != null) { debugResponse(new String(responseBody)); } TLog.e(this, error.getMessage()); } @Override public void onProgress(int bytesWritten, int totalSize) { super.onProgress(bytesWritten, totalSize); } @Override public void onRetry(int retryNo) { makeText(String.format("Request is retried, retry no. %d", retryNo)); } }); } else if (view == mJsonButton) { url = "http://httpbin.org/headers"; mTAsyncHttpClient.get(this, url, null, null, new BaseJsonHttpResponseHandler<SampleJSON>() { @Override public void onStart() { } @Override public void onSuccess(int statusCode, Header[] headers, String rawJsonResponse, SampleJSON response) { debugHeaders(headers); debugStatusCode(statusCode); if (response != null) { debugResponse(rawJsonResponse); } } @Override public void onFailure(int statusCode, Header[] headers, Throwable throwable, String rawJsonData, SampleJSON errorResponse) { debugHeaders(headers); debugStatusCode(statusCode); debugThrowable(throwable); if (errorResponse != null) { debugResponse(rawJsonData); } } @Override protected SampleJSON parseResponse(String rawJsonData, boolean isFailure) throws Throwable { return null; // return new ObjectMapper().readValues( // new JsonFactory().createParser(rawJsonData), // SampleJSON.class).next(); } }); } else if (view == mLoginButton) { url = "http://myendpoint.com"; RequestParams params = new RequestParams(); params.put("username", "banketree"); params.put("password", "111111"); params.put("email", "banketree@qq.com"); // params.put("profile_picture", new File("pic.jpg")); // Upload a // File // params.put("profile_picture2", someInputStream); // Upload // anInputStream // map = new HashMap<String, String>(); // map.put("first_name", "James"); // map.put("last_name", "Smith"); // params.put("user", map); // * Set<String> set = new HashSet<String>(); // // unordered collection // * set.add("music"); // * set.add("art"); // * params.put("like", set); // url params: // "like=music&like=art" // // * List<String> list = new ArrayList<String>(); // // Ordered collection // * list.add("Java");<> // * list.add("C"); // * params.put("languages", list); // url params: // "languages[]=Java&languages[]=C" // // * String[] colors = { "blue", "yellow" }; // Ordered collection // * params.put("colors", colors); // url params: // "colors[]=blue&colors[]=yellow" // * // * List<Map<String, String>> listOfMaps = new // ArrayList<Map<String, // * String>>(); // * Map<String, String> user1 = new HashMap<String, // String>(); // * user1.put("age", "30"); // * user1.put("gender", "male"); // * Map<String, String> user2 = new HashMap<String, // String>(); // * user2.put("age", "25"); // * user2.put("gender", "female"); // * listOfMaps.add(user1); // * listOfMaps.add(user2); // * params.put("users", listOfMaps); // url params: // "users[][age]=30&users[][gender]=male&users[][age]=25&users[][gender]=female" // * mTAsyncHttpClient.post(url, params, new AsyncHttpResponseHandler() { @Override public void onStart() { } @Override public void onSuccess(int statusCode, Header[] headers, byte[] response) { debugHeaders(headers); debugStatusCode(statusCode); debugResponse(new String(response)); } @Override public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) { debugHeaders(headers); debugStatusCode(statusCode); debugThrowable(e); if (errorResponse != null) { debugResponse(new String(errorResponse)); } } }); } else if (view == mBinaryButton) { url = "http://httpbin.org/gzip"; mTAsyncHttpClient.get(this, url, getRequestHeaders(), null, new BinaryHttpResponseHandler() { @Override public void onStart() { } @Override public String[] getAllowedContentTypes() { // Allowing all data for debug purposes return new String[] { ".*" }; } public void onSuccess(int statusCode, Header[] headers, byte[] binaryData) { debugStatusCode(statusCode); debugHeaders(headers); debugResponse("Received response is " + binaryData.length + " bytes"); } @Override public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) { debugHeaders(headers); debugStatusCode(statusCode); debugThrowable(e); if (errorResponse != null) { debugResponse("Received response is " + errorResponse.length + " bytes"); } } }); } else if (view == mSynGetButton) { url = "https://httpbin.org/delay/6"; mTSyncHttpClient.get(this, url, getRequestHeaders(), null, new AsyncHttpResponseHandler() { @Override public void onStart() { } @Override public void onSuccess(final int statusCode, final Header[] headers, final byte[] response) { debugHeaders(headers); debugStatusCode(statusCode); debugResponse(new String(response)); } @Override public void onFailure(final int statusCode, final Header[] headers, final byte[] errorResponse, final Throwable e) { debugHeaders(headers); debugStatusCode(statusCode); debugThrowable(e); if (errorResponse != null) { debugResponse(new String(errorResponse)); } } }); } else if (view == mTimeOutButton) { url = "http://httpbin.org/delay/6"; mTAsyncHttpClient.get(this, url, getRequestHeaders(), null, new AsyncHttpResponseHandler() { private int counter = 0; private int id = counter++; private SparseArray<String> states = new SparseArray<String>(); @Override public void onStart() { setStatus(id, "START"); } @Override public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) { setStatus(id, "SUCCESS"); } @Override public void onFinish() { setStatus(id, "FINISH"); } @Override public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) { setStatus(id, "FAILURE"); } @Override public void onCancel() { setStatus(id, "CANCEL"); } private synchronized void setStatus(int id, String status) { String current = states.get(id, null); states.put(id, current == null ? status : current + "," + status); for (int i = 0; i < states.size(); i++) { debugResponse(String.format("%d (from %d): %s", states.keyAt(i), counter, states.get(states.keyAt(i)))); } } }); }
结束
此框架参考了ThinkAndroid,在写此项目之前,笔者一直使用ThinkAndroid框架开发项目,所以很多思想来源于此。Think框架介绍如下:
ThinkAndroid是一个免费的开源的、简易的、遵循Apache2开源协议发布的Android开发框架,其开发宗旨是简单、快速的进行Android应用程序的开发,包含Android mvc、简易sqlite orm、ioc模块、封装Android httpclitent的http模块,具有快速构建文件缓存功能,无需考虑缓存文件的格式,都可以非常轻松的实现缓存,它还基于文件缓存模块实现了图片缓存功能,在android中加载的图片的时候,对oom的问题,和对加载图片错位的问题都轻易解决。他还包括了一个手机开发中经常应用的实用工具类,如日志管理,配置文件管理,android下载器模块,网络切换检测等等工具。
下载地址:https://github.com/white-cat/ThinkAndroid
相关推荐
兼容 Node.js API 的 Android 本地服务器框架。支持 libUV, TCP, UDT, HTTP/HTTPP, WebSocket.特性:Node.js 0.10.x compatible APIlibUV native supportTimer, set/clear Timeout/...
android_src_tree
android 树开结构+checkobx
Ext4+JSON+Servlet/Struts2+Ext.tree.Panel+Ext.tab.Panel构建Web应用系统框架
android ListView tree lib
android应用源码tree目录和读取word文档整合源码,android安卓实例应用源代码,仅供学习及设计参考。
Android应用源码ListView实现的目录树结构
Android 应用开发源码 参考与学习使用
android应用源码tree目录和读取word文档整合.zip源码资源下载android应用源码tree目录和读取word文档整合.zip源码资源下载
包jar包含 tableView控件,tree控件 图片控件 二维码扫码生成控件,文件选择控件 file ,k可调用readme类获取使用方法,解析后可获取里面用到的jar包
Android:Android酷安Tree应用源码
自己编写的EXT例子,grid、tree从数据库读取数据动态显示,并进行分页。可以动态更换主题,并存入cookies中。
This Android library makes it very easy to create tree menus in an Android APP . You need not write xml files any more to create tree menus By using TreeMenu. You can easily create a three-layer tree...
在对RN-Tree原理分析的基础上,将RN-Tree应用于组P2P网络的多集群网格系统中,研究其查找过程以及查找性能。在单机上编程模拟了多集群网格系统的RN-Tree生成过程及查找过程。模拟方式能够避免在真实的大规模多集群网格...
在对RNTree原理分析的基础上,将RNTree应用于组成P2P网络的多集群网格系统中,研究其查找过程以及查找性能。在单机上编程模拟了多集群网格系统的RNTree生成过程及查找过程。模拟方式能够避免在真实的大规模多...
Android 树形结构开发demo,实现单选多选功能
virtualtree virtualstringtree delphi virtualtree virtualstringtree delphi virtualtree virtualstringtree delphi 花了好长时间写的
ExtJs框架系列之filetree,很有用的源码