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
原创粉丝点击