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();
Adapter适配器:
/**
* 把当前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对象然后把该对象设置给对话框,这样就可以自定义对话框的显示样式了