最近看到谷歌官网上关于提升画面加载的教程,对于XML文件的认识又多了一些。
1.layout的深度不能太大,不然会严重影响加载界面的速度,能够平行布局就尽量平行布局。
2.利用include和merge标签来进行界面的复用。
3.使用ViewStub来自主决定什么时候加载。一个ViewStub包含有它自己的inflatedid以及layout,但是它平时是不会主动加载的,只有当需要时,自己调用inflate方法才会加载该界面。这样就可以让界面初始化时忽略该View从而提升速度。
4.使用另外的线程来处理可能会耗时比较多的操作。例如AsyncTask。
5.使用ViewHolder来存储已经加载好的View。先创建一个ViewHolder类,然后将加载好的View资源存放到里面,下次使用时就可以直接找到,而不用继续使用findViewById方法。
这五种方法里面,曾经在壁纸程序里接触过AsyncTask,但那时候并没有弄懂AsyncTask的工作原理,结合网上前辈的代码,现在总算大概弄明白了。写了一个简单的访问网络的demo,一个EditView,一个Button,一个TextView。代码如下:
package com.example.asynctaskex;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends Activity implements OnClickListener{
private EditText url;
private TextView message;
private Button button;
private void log(String s){
Log.i("bruce",s);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
url = (EditText)findViewById(R.id.etx);
message = (TextView)findViewById(R.id.textView1);
button = (Button)findViewById(R.id.btn);
button.setOnClickListener(this);
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
connect();
}
public void connect(){
PageTask pageTask = new PageTask(this);
//通过AsyncTask来处理输入的网址。
pageTask.execute("http://"+url.getText().toString());
}
class PageTask extends AsyncTask<String, Integer, String>{
/*
* AsyncTask(arg1,arg2,arg3)其中arg1就是输入的网址,类型为String。arg2是中间参数,
* 用来实现ProgressBar的更新。arg3是doInBackground方法处理的结果,也是要传入最后调用方法
* onPostExecute(String s)的参数。AsyncTask必需实现两个方法doInBackground和onPostExecute
* 一个是对输入的内容进行处理,一个是对处理的结果进行显示。
*/
ProgressDialog dialog;
public PageTask(Context contex){
/*
* 构造函数,参数为Context。在构造的时候就定义好一个要用到的ProgressDialog,用于处理过程中
* 显示处理进度。
*/
dialog = new ProgressDialog(contex, 0);
dialog.setButton("cancel", new DialogInterface.OnClickListener() {
//在ProgressDialog中添加一个退出按钮。
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
dialog.cancel();
}
});
/*
* 这里退出按钮进行了分步,单击按钮时只是cancel,当cancel方法调用时setOnCancelListener
* 随之被触发,可以在这里加一些其他的处理。这里是直接关掉整个Activity,正常情况下,不用复写,
* 直接cancel退出diaglog就好
*/
dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
//ProgressDialog的cancel调用时会运行该方法。
@Override
public void onCancel(DialogInterface dialog) {
// TODO Auto-generated method stub
finish();
}
});
dialog.setCancelable(true);
dialog.setMax(100);
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.show();
}
/*
* pageTask.execute(),这个方法调用的时候就会蹦到onPreExecute()去,onPreExecute()之后
* 就是doInBackground了。参数中的String... params表示该参数的个数是可变的,可以传入多个,但
* 必需都是String类型的。多个参数会以数组的形式存在params[]中。这里默认的第一个参数就是params[0]
*
*/
@Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
//获得当前的网络状态
ConnectivityManager conManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = conManager.getActiveNetworkInfo();
log("networkInfo"+networkInfo);
log("networkInfo.isConnected()"+networkInfo.isConnected());
try{
if(networkInfo != null && networkInfo.isConnected()){
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(params[0]);
HttpResponse response = client.execute(get);
HttpEntity entity = response.getEntity();
long length = entity.getContentLength();
InputStream stream = entity.getContent();
String s = null;
if(stream != null){
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
byte[] buf = new byte[128];
int ch = -1;
int count = 0;
while((ch = stream.read(buf)) != -1){
outputStream.write(buf, 0, ch);
count += ch;
if(length > 0){
publishProgress((int)(count/length)*100);
//publishProgress方法执行后就会执行 onProgressUpdate方法
}
}
s = new String(outputStream.toByteArray());
}
return s;
}else{
return null;
}
}catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
message.setText(result);
dialog.dismiss();
}
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
message.setText("task started");
}
@Override
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
message.setText(""+values[0]);
dialog.setProgress(values[0]);
}
}
}