校园助手APP--简介及框架

来源:互联网 发布:淘宝网长款毛衣 编辑:程序博客网 时间:2024/04/26 18:54

最近没有怎么编码,就把断断续续做了半年的毕业设计拿出来回顾一下。

校园助手,分为服务器端与Android客户端,在此主要介绍客户端,服务器是一位大神用node.js写的。

主要实现的功能有:登陆,信息查询,地图,订餐,网页的调用与解析,主要费劲的就是界面。


客户端的框架是参照网上讲解新浪微博客户端的视频。在现在的工作中经常遇到界面更新的不便,但是这个框架就很解决了这个问题,只是刚入门的我还不知道,遇到很多挫折之后才发现这个框架的便捷。下面就开始简单描述一下:

public class MainService extends Service implements Runnable {private static final String TAG = "MainService";private static Queue<Task> tasks = new LinkedList<Task>();private static ArrayList<Activity> appActivities = new ArrayList<Activity>();/** * 标志执行任务的线程是否启动 */public static boolean isRun;/** * 系统当前的用户 */public static UserInfo nowUser;/** * 标志当前网络是否可用 */public static boolean isNetAvailable = false;@Overridepublic void onCreate() {//启动线程执行任务Thread thread = new Thread(this);thread.start();isRun = true;//启动一个新线程获取网络状态new Thread(new Runnable() {@Overridepublic void run() {//一直获取网络状态isNetAvailable = NetService.getNetWorkState(MainService.this);}}).start();super.onCreate();}@Overridepublic IBinder onBind(Intent intent) {return null;}/** * 添加一个Activity对象 在每个Activity启动的时候就调用这个函数,将自己的引用加入到主服务,便于管理,更方便界面的更新 * @param activity */public static void addActivity(Activity activity) {if (!appActivities.isEmpty()) {for (Activity at : appActivities) {if (at.getClass().getName().equals(activity.getClass().getName())) {appActivities.remove(at);break;}}}appActivities.add(activity);}/** * 根据Activity 的Name 获取Activity对象 需要界面的引用时,就从列表获取,很方便地得到界面的引用,从而更新界面 * @param name * @return */private static Activity getActivityByName(String name) {if (!appActivities.isEmpty()) {for (Activity activity : appActivities) {if (null != activity) {if (activity.getClass().getName().indexOf(name) > 0) {return activity;}}}}return null;}/** * 新建任务 界面需要执行耗时操作时,就调用此函数,将任务交给service执行,当执行完后就调用activity的引用来更新界面 * @param t */public static void newTask(Task t) {tasks.add(t);}/** * 主服务启动后,一直从任务队列中取出任务执行 */public void run() {while (isRun) {Task task = null;if (!tasks.isEmpty()) {task = tasks.poll();// 执行完任务后把改任务从任务队列中移除if (null != task) {doTask(task);}}}}// 处理任务private void doTask(Task t) {Message msg = handler.obtainMessage();msg.what = t.getTaskId();switch (t.getTaskId()) {                                //直接在这里进行耗时的操作                //最好将各模块进行封装,从而使主服务的代码简洁明了case Task.USER_LOGIN: {UserInfo loginUser = (UserInfo) t.getTaskParams().get("loginUser");if (null != loginUser) {nowUser = LoginService.login(loginUser);//耗时操作msg.obj = nowUser;Log.i(TAG, "用户登录————————>" + nowUser.getUserName());}break;}default:break;}// end of switchhandler.sendMessage(msg);}/** * 异步处理消息 */@SuppressLint("HandlerLeak")public static Handler handler = new Handler() {public void handleMessage(android.os.Message msg) {IAssistantActivity activity = null;switch (msg.what) {//处理耗时操作后,发送过来的消息//将结果通过参数传过来,然后通过activity的引用传入界面case Task.USER_LOGIN: {if (null != msg.obj) {activity = (IAssistantActivity) getActivityByName("LoginActivity");}break;}default:break;}//end of switch//通过activity的引用调用相应界面的更新函数activity.refresh(msg.obj);};};/** * 退出系统 退出系统时,很方便地清楚掉所有的activity * @param context */public static void appExit(Context context) {// Finish 所有的Activityfor (Activity activity : appActivities) {if (!activity.isFinishing())activity.finish();}// 结束 ServiceIntent service = new Intent("cn.edu.wit.services.MainService");context.stopService(service);}}

这个主服务基本可以完全复用,根据需求添加一些内容即可。

再来看看界面这边是如何搭建的

public class LoginActivity extends Activity implements IAssistantActivity {public static final String TAG = "LoginActivity";private ProgressDialog progressDialog = null;private Button btn_Login;private ClearEditText etUserId;private ClearEditText etPassword;private CheckBox cbIsRemember;private CheckBox cbIsAuto;private ImageButton ib_spinner;protected View listView;private PopupWindow pop;private List<String> userIDs ;private List<UserInfo> loginedUsers ;private MyAdapter adapter;private Animation shake ;private UserInfoServices userInfoServices = null;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.login);//初始化界面init();}@Overridepublic void init() {                //确保主服务已启动if(!MainService.isRun){Intent service = new Intent(this, MainService.class);startService(service);}//获取所有用户,添加到登陆框的下拉列表中userInfoServices = new UserInfoServices(LoginActivity.this);//获取所用用户initData();initView();// 把自己添加到Activity集合里面MainService.addActivity(this);}/** * 初始化界面 */private void initView() {                //一个抖动动画shake = AnimationUtils.loadAnimation(LoginActivity.this, R.anim.shake);etUserId = (ClearEditText) findViewById(R.id.userid);etPassword = (ClearEditText) findViewById(R.id.password);cbIsRemember = (CheckBox) findViewById(R.id.isremember);cbIsAuto = (CheckBox) findViewById(R.id.isAuto);TextView tvGetPassword = (TextView) findViewById(R.id.tvGetPassword);//"找回密码"下划线,为文字添加下划线tvGetPassword.getPaint().setFlags(Paint.UNDERLINE_TEXT_FLAG);tvGetPassword.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View arg0) {Intent intent = new Intent(LoginActivity.this, FindPwdActivity.class);startActivity(intent);overridePendingTransition(SwitchActivityAnim.rightIn(), SwitchActivityAnim.rightOut());}});//登录按钮btn_Login = (Button) findViewById(R.id.login_ok);btn_Login.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {String userId = etUserId.getText().toString().trim();String password = etPassword.getText().toString().trim();if (!"".equals(userId) && !"".equals(password)) {Log.i(TAG, "click login");UserInfo loginUser = new UserInfo();loginUser = new UserInfo();loginUser.setUserId(userId);loginUser.setPassword(password);// 调用函数创建新任务newTask(loginUser);} else {if ("".equals(userId)) {//输入框为空时就抖动etUserId.startAnimation(shake);etUserId.setHint("学号不能为空");etUserId.setHintTextColor(Color.RED);} else {etPassword.startAnimation(shake);etPassword.setHint("密码不能为空");etPassword.setHintTextColor(Color.RED);}}}});//下拉列表显示已登录过的用户ib_spinner = (ImageButton) findViewById(R.id.ib_spinner);ib_spinner.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// 弹出下拉列表ListView listView = new ListView(getApplicationContext());listView.setCacheColorHint(0x00000000);// 滑动时 不变色listView.setVerticalScrollBarEnabled(false);listView.setBackgroundColor(getResources().getColor(R.color.white));//设置透明度listView.getBackground().setAlpha(230);listView.setAdapter(new MyAdapter());pop = new PopupWindow(listView, etUserId.getWidth()+ib_spinner.getWidth(),LayoutParams.WRAP_CONTENT, true);// pop隐藏pop.setBackgroundDrawable(new ColorDrawable(0x00000000));pop.setOutsideTouchable(true);pop.setFocusable(true);//pop.setAnimationStyle(R.style.PopupAnimation);pop.showAsDropDown(etUserId, 0, -8);pop.update();}});}                //将耗时的操作封装后交给主服务private void newTask(UserInfo loginUser) {if(!MainService.isNetAvailable){Toast.makeText(LoginActivity.this, "网络不可用!", Toast.LENGTH_LONG).show();}else {Map<String, Object> taskParams = new HashMap<String, Object>();taskParams.put("loginUser", loginUser);Task task = new Task(Task.USER_LOGIN, taskParams);//将任务加入主服务线程MainService.newTask(task);showDialg();}}/**主服务处理完任务后,通过引用来调用此函数来达到更新界面的目的 * 更新登录界面,或登录成功后跳转,或显示错误信息 */@Overridepublic void refresh(Object... obj) {progressDialog.dismiss();if (null != obj[0]) {if (obj[0] instanceof Exception) {Exception exception = (Exception) obj[0];System.out.println(exception.getMessage());Toast.makeText(this, "登录失败!", Toast.LENGTH_SHORT).show();return;}UserInfo user = (UserInfo)obj[0];if (null == user.getUserName() || "".equals(user.getUserName())) {//用户名密码错误Toast.makeText(this, "登录失败!", Toast.LENGTH_SHORT).show();Toast.makeText(this, "请核查用户名密码以及网络连接是否可用", Toast.LENGTH_LONG).show();}else {//登录成功,跳转到主界面Toast.makeText(LoginActivity.this, "登录成功!", Toast.LENGTH_SHORT).show();Toast.makeText(LoginActivity.this, "欢迎 "+user.getUserName()+"童鞋", Toast.LENGTH_SHORT).show();int isRemember = cbIsRemember.isChecked() ? 1 :0 ;int isAuto = cbIsAuto.isChecked() ? 1 :0 ;// 跳转Intent intent = new Intent(LoginActivity.this, HomeActivity.class);startActivity(intent);overridePendingTransition(SwitchActivityAnim.fadeIn(), SwitchActivityAnim.bloomOut());if (1 == isAuto) {//自动登录则存入数据库,且写到配置文件SharedPreferencesUtil.saveLoginUser(LoginActivity.this, user);userInfoServices.insertUserInfo(user);}else if (1 == isRemember) {//记住密码就写入数据库userInfoServices.insertUserInfo(user);}this.finish();}}else {Toast.makeText(LoginActivity.this, "登录失败", Toast.LENGTH_LONG).show();}}private void initData(){userIDs = new ArrayList<String>();loginedUsers = userInfoServices.getAllLoginedUser();String users = "";if (null != loginedUsers && loginedUsers.size() > 0) {for (UserInfo user : loginedUsers) {userIDs.add(user.getUserId());users += user.getUserId()+"\t  密码:"+user.getPassword()+"\n";}System.out.println(users);}}//将已登录的用户列表适配到下拉列表class MyAdapter extends BaseAdapter {@Overridepublic int getCount() {return userIDs.size();}@Overridepublic Object getItem(int position) {return userIDs.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(final int position, View convertView,ViewGroup parent) {LayoutInflater inflater = LayoutInflater.from(getApplicationContext());View view = inflater.inflate(R.layout.item_userids, parent, false);TextView tv_name = (TextView) view.findViewById(R.id.tv_name);ImageButton delete = (ImageButton) view.findViewById(R.id.delete);tv_name.setText(userIDs.get(position));tv_name.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {etUserId.setText(userIDs.get(position));etPassword.setText(loginedUsers.get(position).getPassword());pop.dismiss();}});delete.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {userIDs.remove(position);adapter.notifyDataSetChanged();}});return view;}}private void showDialg() {if (null == progressDialog  ) {progressDialog = new ProgressDialog(this);}progressDialog.setMessage("正在获取信息...");progressDialog.show();}}

通过注释应该能够看清楚。


我是通过这个项目来学Android的,所以这里面没有太多的Android处理技巧,由于工作的原因,只是用以前的代码,并没有优化。当让这样也能让自己看到慢慢成长的过程。

本文出自 “年少的风” 博客,谢绝转载!

0 0
原创粉丝点击