Android学习(22)-实战要点
来源:互联网 发布:淘宝运营费用 编辑:程序博客网 时间:2024/05/01 05:34
在实际项目中,合理的项目结构是非常重要的,下面讲一下一般的结构形式。
各种包和类的作用:
activity: 活动相关代码
db: 数据库操作相关代码
model: 模型,简单实体类代码
receiver: 广播接收器相关代码
service: 服务相关代码
util: 工具相关代码
1、db中如何合理设计代码结构?
RealProjectOpenHelper类,继承自SQLiteOpenHelper类,用于创建数据库和各种表。
RealProjectDB类,最好是单例模式,各种操作数据库的函数,如增删改查功能。借助于RealProjectOpenHelper类获取数据库操作句柄。
public class RealProjectOpenHelper extends SQLiteOpenHelper {//创建三个数据表的语句public static final String CREATE_PROVINCE = "create table Province(id integer primary key autoincrement, province_name text, province_code text)";public static final String CREATE_CITY = "create table City(id integer primary key autoincrement, city_name text, city_code text, province_id integer)";public static final String CREATE_COUNTY = "create table County(id integer primary key autoincrement, county_name text, county_code text, city_id integer)";//构造函数public RealProjectOpenHelper(Context context, String name, CursorFactory factory, int version){super(context, name, factory, version);}//数据库创建@Overridepublic void onCreate(SQLiteDatabase db) {db.execSQL(CREATE_PROVINCE);db.execSQL(CREATE_CITY);db.execSQL(CREATE_COUNTY);}//涉及到更新,此处的更新还是比较弱 参考之前的博文 知道如何更好的控制更新内容@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {db.execSQL("drop table if exists Province"); db.execSQL("drop table if exists City");db.execSQL("drop table if exists County"); onCreate(db); }}
以及:
public class RealProjectDB {//数据库名字public static final String DB_NAME = "cool_weather";//数据库版本public static final int VERSION = 1;//单例模式使用private static RealProjectDB realprojectDB;private SQLiteDatabase db;private RealProjectDB(Context context){//创建数据库 获取数据库操作句柄 这里是关键 为后续的对数据库的操作提供保障RealProjectOpenHelper rpHelper = new RealProjectOpenHelper(context, DB_NAME, null, VERSION);db = rpHelper.getWritableDatabase();}//线程安全的创建类实例public static RealProjectDB getInstance(Context context){if(realprojectDB == null) { //(1) //只有第一次才彻底执行这里的代码 synchronized(RealProjectDB.class){ //再检查一次 if(realprojectDB == null) realprojectDB = new RealProjectDB(context); } } return realprojectDB; }/** * 保存省份信息 * @param p */public void saveProvince(Province p){if(p != null){ContentValues values = new ContentValues();values.put("province_name", p.getProvinceName());values.put("province_code", p.getProvinceCode());db.insert("Province", null, values);}}/** * 获取所有省份信息 * @return */public List<Province> loadProvinces(){List<Province> list = new ArrayList<Province>();//查询数据Cursor cursor = db.query("Province", null, null, null, null, null, null);if(cursor.moveToFirst()){do{Province p = new Province();p.setId(cursor.getInt(cursor.getColumnIndex("id")));p.setProvinceName(cursor.getString(cursor.getColumnIndex("province_name")));p.setProvinceCode(cursor.getString(cursor.getColumnIndex("province_code")));list.add(p);}while(cursor.moveToNext());}return list;}//还是保存城市乡村信息和获取城市乡村信息 不再一一列出}
2、有很多操作是需要访问服务器获取返回信息,此时就设计通用的类来做这件事情。
可以参考代码如下:
/** * 与服务器交互类 * @author Administrator * */public class HttpUtil {/** * 向服务器发送请求方法 * @param address * @param listener */public static void sendHttpRequest(final String address, final HttpCallbackListener listener){new Thread(new Runnable() {public void run() {HttpURLConnection connection = null;try{//建立连接URL url = new URL(address);connection = (HttpURLConnection)url.openConnection();connection.setRequestMethod("GET");connection.setConnectTimeout(8000);connection.setReadTimeout(8000);//获取输入流InputStream in = connection.getInputStream();BufferedReader reader = new BufferedReader(new InputStreamReader(in));//获取返回的内容 通过StringBuilder进行拼接StringBuilder response = new StringBuilder();String line;while((line = reader.readLine()) != null){response.append(line);}if(listener != null){//回调onFinish方法listener.onFinish(response.toString());}}catch(Exception e){if(listener != null){//回调onError方法listener.onError(e);}}finally{connection.disconnect();}}}).start();}}这个方法中用到了一个接口参数,该接口很简单:
/** * 回调接口 * @author Administrator * */public interface HttpCallbackListener {void onFinish(String response);void onError(Exception e);}
个人理解:这个方法非常牛逼和通用,根据传递的地址获取到服务器端返回的数据,然后调用接口中的方法,这个时候就非常的灵活了,因为不同功能点对于该接口的实现方法不同,比如,在下面的应用中,可以如是调用代码:
//从服务器获取数据private void queryFromServer(final String code, final String type){String address;if(!TextUtils.isEmpty(code)){address = "http://...."; //根据不同的code,设置不同的服务器地址}else{address = "";}//加载的时候,展示进度条showProgressDialog();//在此处确定地址,然后对于返回的数据编写回调函数<span style="color:#ff0000;">HttpUtil.sendHttpRequest(address, new HttpCallbackListener() {</span>@Override<span style="color:#ff0000;">public void onFinish(String response)</span> {boolean result = false;if("province".equals(type)){result = Utility.handleProvinceResponse(db, response);}//去过是其他的,调用其他方法//如果返回数据处理成功if(result){<span style="color:#ff0000;">//回到主线程中runOnUiThread(new Runnable() {</span>@Overridepublic void run() {closeProgressDialog();if("province".equals(type)){queryProvinces();}//如果是其他的,获取城市或者县城数据。}});}}@Override<span style="color:#ff0000;">public void onError(Exception e) {</span>runOnUiThread(new Runnable() {@Overridepublic void run() {closeProgressDialog();Toast.makeText(ChooseAreaActivity.this, "加载失败", Toast.LENGTH_SHORT).show();}});}});}
3、数据的存储思路
如果是一些长期需要用到的数据,比如所有省份,城市信息等,那么可以存到本地数据库中,在获取数据的时候先从本地数据库获取,如果没有,那么从服务器端获取,对于返回的数据进行处理,处理的过程中存入到数据库中。如果是一些临时信息,思路是一样的,但是可以先存储在SharedPreferences中。
另外,还有一些变量用于判断某些事情发生或者没有发生,根据这些变量来做进一步的操作。此时也可以通过SharedPreferences来存储。
4、如何实现定时任务?
可以在后台启动服务,然后通过定时器启动接收器,在接收器中重新开启服务,就是这种周而复始的搞下去。就达到了定时任务的效果。
在服务中,代码核心如下:
public class AutoUpdateService extends Service {@Overridepublic IBinder onBind(Intent arg0) {// TODO Auto-generated method stubreturn null;}public int onStartCommand(Intent intent, int flags, int startId){//开启子线程调用定时任务new Thread(new Runnable() {@Overridepublic void run() {doSomething();}}).start();//获取广播AlarmManager manager = (AlarmManager)getSystemService(ALARM_SERVICE);int anHour = 8 * 60 * 60 * 1000;long triggerAtTime = SystemClock.elapsedRealtime()+anHour;Intent i = new Intent(this,AutoUpdateReceiver.class);PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0);manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pi);return super.onStartCommand(intent, flags, startId);}//定时操作public void doSomething(){}}
接收器代码如下:
public class AutoUpdateReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context arg0, Intent arg1) {Intent i = new Intent(arg0,AutoUpdateService.class);arg0.startService(i);}}
0 0
- Android学习(22)-实战要点
- android学习要点总结
- Android学习要点记录
- Android学习要点
- 黑客攻防实战学习要点总结
- Android学习基础要点总结
- 机器学习实战—朴素贝叶斯及要点注解
- Maven 实战要点
- node.js实战 要点
- node.js实战 要点
- android doc例程---Notepad Tutorial学习要点!
- JavaScript学习要点(一)
- JavaScript学习要点(二)
- JavaScript学习要点(三)
- JavaScript学习要点(四)
- JavaScript学习要点(五)
- JavaScript学习要点(六)
- JavaScript学习要点(七)
- ExtJs之组件(window)
- 无法打开包含文件#include”cxtypes.h”问题————OpenCV笔记
- 动态链接库的RPATH和RUNPATH解惑
- SUSE Install Oracle
- uva 10163 Storage Keepers
- Android学习(22)-实战要点
- ExtJs之列表(grid)
- ORACLE常用数值函数、转换函数、字符串函数
- interface脱耦合和Android当中onclickListener接口浅析
- Roman to Integer - LeetCode
- 使用OpenMP给程序加速
- SIGPIPE信号详解
- 视频封装格式详解
- 编译hadoop2.6.0 --- 64位源代码(能力工场收集)