Splash和应用程序的升级和显示主界面
新建第一个类Splash.java
首先说一下Splash.java类的作用,一般来说一个android应用都应该有一个这样的类,这个类的有如下作用:
1.数据库的下载和创建
2.检测服务器上最新的版本信息.
3.根据不同的日期时间展现不同的logo.
4.检测用户的手机网络.
下面这个类有体现:
1 // 连接服务器失败 2 public static final int CONNECT_SERVER_ERROR = 10; 3 // 显示提示信息 4 public static final int SHOW_UPDATE_DIALOG = 11; 5 // 下载失败 6 public static final int DOWNLOAD_ERROR = 12; 7 // 下载成功 8 public static final int DOWNLOAD_SUCCESS = 13; 9 public static final String TAG = "SplashActivity"; 10 11 UpdateInfo info; 12 String version; 13 ProgressDialog pd; 14 15 //使用Handler和message更新界面 16 private Handler handler = new Handler() { 17 @Override 18 public void handleMessage(Message msg) { 19 super.handleMessage(msg); 20 switch (msg.what) { 21 case CONNECT_SERVER_ERROR: 22 Toast.makeText(SplashActivity.this, "连接服务器异常", 1).show(); 23 Log.i(TAG, "进入程序主界面 "); 24 LoadMainUI(); 25 break; 26 case SHOW_UPDATE_DIALOG: 27 AlertDialog.Builder builder = new Builder(SplashActivity.this); 28 builder.setTitle("升级提醒"); 29 builder.setMessage(info.getDescription()); 30 31 builder.setPositiveButton("是", new OnClickListener() { 32 public void onClick(DialogInterface dialog, int which) { 33 Log.i(TAG, "根据info对象里面的url下载最新的apk"); 34 String apkpath = info.getUrl(); 35 // DownLoadFileService.downLoad(apkpath); 36 pd.setMessage("正在下载更新"); 37 pd.show(); 38 new Thread(new DownLoadFileTask(apkpath)).start(); 39 } 40 }); 41 builder.setNegativeButton("否", new OnClickListener() { 42 43 public void onClick(DialogInterface dialog, int which) { 44 Log.i(TAG, "什么事情也不做进入程序主界面 "); 45 LoadMainUI(); 46 } 47 48 }); 49 builder.create().show(); 50 break; 51 52 case DOWNLOAD_ERROR: 53 Toast.makeText(SplashActivity.this, "下载更新失败", 1).show(); 54 Log.i(TAG, "进入程序主界面 "); 55 pd.dismiss(); 56 LoadMainUI(); 57 break; 58 case DOWNLOAD_SUCCESS: 59 pd.dismiss(); 60 Log.i(TAG, "安装新的apk"); 61 File file = (File) msg.obj; 62 //下载成功后安装apk 63 installApk(file); 64 break; 65 } 66 } 67 68 }; 69 70 /** 71 * 加载主界面 72 */ 73 private void LoadMainUI() { 74 Intent intent = new Intent(this, MainActivity.class); 75 startActivity(intent); 76 finish(); 77 } 78 79 /** 80 * 安装apk 81 */ 82 private void installApk(File file) { 83 Intent intent = new Intent(); 84 // 查看的意图 (动作) 85 intent.setAction(Intent.ACTION_VIEW); 86 87 /* 88 * 不能先设置data再设置type这样会把data清除掉,所有使用setDataAndType 89 * intent.setData(Uri.fromFile(file)); //mime 的数据类型 90 * intent.setType("application/vnd.android.package-archive"); 91 */ 92 93 // MIME类型可以在tomcat里面的web.xml文件找到 94 intent.setDataAndType(Uri.fromFile(file), 95 "application/vnd.android.package-archive"); 96 finish(); 97 startActivity(intent); 98 } 99 100 @Override 101 public void onCreate(Bundle savedInstanceState) { 102 103 // 全屏显示 104 requestWindowFeature(Window.FEATURE_NO_TITLE); 105 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 106 WindowManager.LayoutParams.FLAG_FULLSCREEN); 107 108 super.onCreate(savedInstanceState); 109 setContentView(R.layout.splash); 110 111 112 //进度条对话框的初始化 113 pd = new ProgressDialog(this); 114 //进度条的样式为水平进度 115 pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); 116 117 RelativeLayout rl = (RelativeLayout) this.findViewById(R.id.rl_splash); 118 //渐变动画 119 AlphaAnimation aa = new AlphaAnimation(0.0f, 1.0f); 120 TextView tv = (TextView) this.findViewById(R.id.tv_version); 121 //动画的时间 122 aa.setDuration(4000); 123 //把动画作用到相对布局上(rl) 124 rl.setAnimation(aa); 125 126 version = getAppVersion(); 127 // 显示当前程序的版本号 128 tv.setText(version); 129 130 //if( 判断是否检查需要更新 ) 131 //创建线程 访问服务器 获取服务器上的版本信息 132 new Thread(new CheckVersionTask()).start(); 133 134 135 } 136 137 /** 138 * 获取版本号 139 * @return 140 */ 141 private String getAppVersion() { 142 try { 143 PackageManager packageManager = this.getPackageManager(); 144 145 // 第二个参数指定返回的数据,我们只需要版本信息,传入0即可 146 PackageInfo packInfo = packageManager.getPackageInfo( 147 getPackageName(), 0); 148 return packInfo.versionName; 149 } catch (NameNotFoundException e) { 150 e.printStackTrace(); 151 Toast.makeText(this, "获取版本好失败", 0).show(); 152 } 153 return null; 154 } 155 156 private class DownLoadFileTask implements Runnable { 157 String apkpath; 158 159 public DownLoadFileTask(String apkpath) { 160 this.apkpath = apkpath; 161 } 162 163 public void run() { 164 try { 165 File file = DownLoadFileService.downLoad(apkpath, pd); 166 Message msg = new Message(); 167 msg.obj = file; 168 msg.what = DOWNLOAD_SUCCESS; 169 handler.sendMessage(msg); 170 } catch (Exception e) { 171 e.printStackTrace(); 172 Message msg = new Message(); 173 msg.what = DOWNLOAD_ERROR; 174 handler.sendMessage(msg); 175 } 176 } 177 178 } 179 180 /** 181 * 检查服务器获取 最新的版本信息 182 * @author Administrator 183 * 184 */ 185 private class CheckVersionTask implements Runnable { 186 187 public void run() { 188 try { 189 String path = getResources().getString(R.string.serverurl); 190 Log.i("SplashActivity", path); 191 URL url = new URL(path); 192 HttpURLConnection conn = (HttpURLConnection) url 193 .openConnection(); 194 conn.setConnectTimeout(3000); 195 InputStream is = conn.getInputStream(); 196 info = UpdateInfoParser.getUpdateInfo(is); 197 // 如果服务上的版本信息 比客户端的信息大 提示用户升级 198 String serverversion = info.getVersion(); 199 if (version.equals(serverversion)) { 200 Log.i(TAG, "版本号相同无需升级"); 201 } else { 202 Log.i(TAG, "版本号不相同提示用户升级"); 203 // 弹出对话框的操作必须在主线程里面 204 Message msg = new Message(); 205 msg.what = SHOW_UPDATE_DIALOG; 206 handler.sendMessage(msg); 207 } 208 } catch (Exception e) { 209 e.printStackTrace(); 210 Message msg = new Message(); 211 msg.what = CONNECT_SERVER_ERROR; 212 handler.sendMessage(msg); 213 } 214 215 } 216 }
MainActivity.java
1 public class MainActivity extends Activity { 2 3 LayoutInflater inflater; 4 GridView gv; 5 @Override 6 protected void onCreate(Bundle savedInstanceState) { 7 super.onCreate(savedInstanceState); 8 setContentView(R.layout.main); 9 10 gv = (GridView) this.findViewById(R.id.gv_main); 11 12 gv.setAdapter(new MainActivityAdapter(this)); 13 14 gv.setOnItemClickListener(new MyItemClickListener()); 15 } 16 17 private class MyItemClickListener implements OnItemClickListener{ 18 19 /** 20 * parent : gridview 21 * view : 被点击的某个条目对应的view对象 linearlayout 22 * position : 被点击的条目对应位置的id 23 * id: 代表的第几行 24 */ 25 public void onItemClick(AdapterView parent, View view, int position, 26 long id) { 27 28 switch (position) { 29 case 0: 30 Intent lostProtectedIntent = new Intent(MainActivity.this,LostProtectedActivity.class); 31 startActivity(lostProtectedIntent); 32 break; 33 } 34 } 35 36 } 37 }
1 View view = inflater.inflate(R.layout.change_name_dialog, null); 2 et_change_name = (EditText) view.findViewById(R.id.et_change_name); 3 Button bt_ok = (Button) view.findViewById(R.id.bt_change_name_ok); 4 Button bt_cancle = (Button) view.findViewById(R.id.bt_change_name_cancle); 5 bt_ok.setOnClickListener(this); 6 bt_cancle.setOnClickListener(this); 7 AlertDialog.Builder builder = new Builder(this); 8 builder.setTitle("请输入修改的标题"); 9 builder.setView(view); 10 dialog = builder.create(); 11 dialog.show();
/** * 把当前item对应的view对象返回回去 * 返回的View是每一个条目的View */ public View getView(int position, View convertView, ViewGroup parent) { SharedPreferences sp = context.getSharedPreferences("config", Context.MODE_PRIVATE); String name = sp.getString("name", "手机防盗"); //通过配置文件返回每一个条目的View对象 View view = inflater.inflate(R.layout.main_item, null); ImageView iv = (ImageView) view.findViewById(R.id.iv_main_item); TextView tv = (TextView)view.findViewById(R.id.tv_main_item); iv.setImageResource(icons[position]); tv.setText(names[position]); boolean isempty = "".equals(name); if((!isempty)&&position==0){ tv.setText(name); } return view; }
总结:
1>一般耗时的操作如访问网络(服务器),下载等,如上面的DownLoadFileTask和CheckVersionTask(他们都实现了Runable)都放在了子线程中来执行new Thread(....).start();
2>在子线程中更新主线程的控件需要使用Handler和Message
3>一般我们通过自己定义的布局文件,获取到View对象然后把该对象设置给对话框,这样就可以自定义对话框的显示样式了