Android的Handle

1:Handle与多线程

Handle是什么?官方说明:handle是Android给我们提供用来更新UI的一套机制,也是一套消息处理的机制。可以看出handle主要就是两个功能,一个是更新UI,另一个就是发送消息和对消息进行处理。

为什么要用Handle?

Handler是Thread的代言人,是多线程之间通信的桥梁,通过Handler,我们可以在一个线程中控制另一个线程去做某事。

    当应用程序启动时,Android首先会开启一个主线程 (也就是UI线程) , 主线程为管理界面中的UI控件, 进行事件分发, 比如说, 你要是点击一个 Button ,Android会分发事件到Button上,来响应你的操作。  如果此时需要一个耗时的操作,例如: 联网读取数据,    或者读取本地较大的一个文件的时候,你不能把这些操作放在主线程中,如果你放在主线程中的话,界面会出现假死现象, 如果5秒钟还没有完成的话,会收到Android系统的一个错误提示  "强制关闭"。  这个时候我们需要把这些耗时的操作,放在一个子线程中,因为子线程涉及到UI更新,,Android主线程是线程不安全的, 也就是说,更新UI只能在主线程中更新,子线程中操作是危险的。 这个时候,Handler就出现了。,来解决这个复杂的问题 ,由于Handler运行在主线程中(UI线程中),  它与子线程可以通过Message对象来传递数据, 这个时候,Handler就承担着接受子线程传过来的(子线程用sedMessage()方法传弟)Message对象,(里面包含数据)  , 把这些消息放入主线程队列中,配合主线程进行更新UI

怎么用Handle机制?

public class MyHandlerActivity extends Activity { 
    MyHandler myHandler; 
    protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.main); 

        myHandler = new MyHandler(); 
        // 当创建一个新的Handler实例时, 它会绑定到当前线程和消息的队列中,开始分发数据 
        // Handler有两个作用, (1) : 定时执行Message和Runnalbe 对象 
        // (2): 让一个动作,在不同的线程中执行。 
 
        // 它安排消息,用以下方法 
        // post(Runnable) 
        // postAtTime(Runnable,long) 
        // postDelayed(Runnable,long) 
        // sendEmptyMessage(int) 
        // sendMessage(Message); 
        // sendMessageAtTime(Message,long) 
        // sendMessageDelayed(Message,long) 
      
        // 以上方法以 post开头的允许你处理Runnable对象 
        //sendMessage()允许你处理Message对象(Message里可以包含数据,) 
 
        MyThread m = new MyThread(); 
        new Thread(m).start(); 
    } 
 
    /** 
    * 接受消息,处理消息 ,此Handler会与当前主线程一块运行 
    * */ 
 
    class MyHandler extends Handler { 
        public MyHandler() { 
        } 
 
        public MyHandler(Looper L) { 
            super(L); 
        } 
 
        // 子类必须重写此方法,接受数据 
        @Override 
        public void handleMessage(Message msg) { 
            // TODO Auto-generated method stub 
            super.handleMessage(msg); 
            // 此处可以更新UI 
            Bundle b = msg.getData();  
            MyHandlerActivity.this.button.append(color); 
 
        } 
    } 
 
    class MyThread implements Runnable { 
        public void run() {  
            try { 
                Thread.sleep(10000); 
            } catch (InterruptedException e) { 
                // TODO Auto-generated catch block 
                e。printStackTrace(); 
            } 

            Message msg = new Message(); 
            Bundle b = new Bundle();// 存放数据 
            b.putString("color", "我的"); 
            msg.setData(b); 
 
            MyHandlerActivity。this。myHandler。sendMessage(msg); // 向Handler发送消息,更新UI 
 
        } 
    } 
} 

 

2:json封装与解析

json数据类型表示:Object ,Array,String,number,true,false,null无其他使用key和value表示

{

"name":"xqc",

"age":25,

"birthday":"1997-07-21",

"major":["JAVA","Android","Python","前端"],

"work":null

}

json的使用 in java:

构建json对象:如果想查看,可以直接System.out.println(xqc.toString())即可

初级:

 1 JSONObject xqc = new JSONObject();
 2 Object nullObj = null//处理冲突
 3 try{
 4      xqc.put("name","xqc");
 5      ......
 6      xqc.put("major",new String[]{"JAVA","Android","Python","前端"});
 7      xqc.put("work",nullObj);
 8 
 9 }catch(JSONException e){
10 e.printStackTrace();
11 }

使用map构建:几乎与上边一样,只是先将对象存于Map,在调用json的构造方法转化为json对象

 1 Map<String,Object> xqc = new HashMap<String,Object>();
 2 Object nullObj = null//处理冲突 4       xqc.put("name","xqc");
 5       ......
 6       xqc.put("major",new String[]{"JAVA","Android","Python","前端"});
 7       xqc.put("work",nullObj); 11 new JSONObject(xqc);

使用javabean构建:开发中常用:先构建JAVABean对象,包含上述属性,生成get和set方法,然后:

1 Person xqc = new Person();
2 xqc.setName("xqc");
3 xqc.setMajor(new String[]{"JAVA","Android","Python","前端"});
4 ......
5 new JSONObject(xqc);

解析json

重文件读取json:将上述json数据存储在xqc.json文件中

1 File file = new File("xqc.json").getFile();
2 String content = FileUtils.readFileToString(file);
3 JSONObject jsonObject = new JSONObject(content);
4 String name = jsonObject.getString("name");
5 .....

Gson的使用

Gson生成json数据:与上述javabean几乎相同用法

1 Person xqc = new Person();
2 xqc.setName("xqc");
3 xqc.setMajor(new String[]{"JAVA","Android","Python","前端"});
4 ......
5  Gson gson = new Gson();
6  gson.toJson(xqc);

Gson解析

1 File file = new File("xqc.json").getFile();
2 String content = FileUtils.readFileToString(file);
3 Gson gson = new Gson();
4 Person xqc = gson.fromJson(content,Person.class);//直接转换为person对象

3:BaseAdapter数据适配器

适配器顾名思义就是将数据源与控件进行合理匹配的一个class,最常见的就是ListView控件的使用

实现四个基本方法:

 1 public class MyAdapter extends BaseAdapter {
 2     // 映射数据
 3     private List<ItemBean> myDataList;
 4 //通过构造方法将数据源与适配器相关联
 5     public MyAdapter(List<ItemBean> list) {
 6         myDataList = list;
 7     }
 8 
 9     // 获取数据量
10     @Override
11     public int getCount() {
12         return myDataList.size();
13     }
14 
15     // 获取对应ID项对应的Item
16     @Override
17     public Object getItem(int position) {
18         return myDataList.get(position);
19     }
20 
21     // 获取对应项ID
22     @Override
23     public long getItemId(int position) {
24         return position;
25     }
26 //获取每一项的具体数据内容内容
27     @Override
28     public View getView(int position, View convertView, ViewGroup parent) {
29 //实现最为复杂,三种实现方式下方介绍
30 }

为了不显得乱,这里就介绍一种开发中常用的: 避免重复findViewById的操作

    private LayoutInflater mLayoutInflater;

//初始化
    public MyAdapter(Context context, List<ItemBean> list) {
        mLayoutInflater = LayoutInflater.from(context);
    }   
 // ViewHolder用于缓存控件
    class ViewHolder{
        public ImageView img;
        public TextView title;
        public TextView content;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
//创建内部类ViewHolder
//判断convertView是否为空
//通过setTag将ViewHolder与convertView绑定
//getTag()取出关联的ViewHodle
//通过ViewHolder对象周到对应的文件
        ViewHolder holder = null;
        if (convertView == null) {
            holder = new ViewHolder();
        // 由于我们只需要将XML转化为View,并不涉及到具体的布局,所以第二个参数通常设置为null
            convertView = mLayoutInflater.inflate(R.layout.item, null);
            holder.img = (ImageView) convertView.findViewById(R.id.iv_image);
            holder.title = (TextView) convertView.findViewById(R.id.tv_title);
            holder.content = (TextView) convertView.findViewById(R.id.tv_content);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        // 取出bean对象/        
        ItemBean bean = mDataList.get(position);
        // 设置控件的数据
        holder.img.setImageResource(bean.itemImageResid);
        holder.title.setText(bean.itemTitle);
        holder.content.setText(bean.itemContent);

        return convertView;
}

 

4:网络通信

写在前面:千万不要忘了添加访问网络权限

<uses-permission android:name= "android.permission.INTERNET" />

Android网络编程分为两种:基于http协议的,和基于socket的。
基于Http协议:HttpClient、HttpURLConnection、AsyncHttpClient框架等
基于Socket:
(1)针对TCP/IP的Socket、ServerSocket
(2)针对UDP/IP的DatagramSocket、DatagramPackage
(3)Apache Mina框架

1.socket套接字:

socket通信的优点就是建立连接后服务器可以主动向客户端发送消息。Socket通信由IP地址和端口号两部分组成。通信时分为服务器端和客户端,在这里仅仅介绍客户端,在建立连接之前,服务器端会一直监听是否有连接的请求,当客户端Socket socket = new Socket(IPAdress, port);后建立连接,当然仅仅连接上是远远不够的,那怎么进行数据传输呐!其实还是用IO流进行传输

public class MainActivity extends Activity {  
    private EditText editText;  
    private Button button;  
    /** Called when the activity is first created. */  
    @Override  
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.main);  
          
        editText = (EditText)findViewById(R.id.editText1);  
        button = (Button)findViewById(R.id.button1);  
          
        button.setOnClickListener(new OnClickListener() {  
            @Override  
            public void onClick(View v) {  
                Socket socket = null;  
                String message = editText.getText().toString()+ "\r\n" ;  
                try {  
                    //创建客户端socket,注意:不能用localhost或127.0.0.1,Android模拟器把自己作为localhost  
                    socket = new Socket("<span style="font-weight: bold;">10.0.2.2</span>",18888);  
                    PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter  
                            (socket.getOutputStream())),true);  
                    //发送数据  
                    out.println(message);  
                      
                    //接收数据  
                    BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));  
                    String msg = in.readLine();  
                    if (null != msg){  
                        editText.setText(msg);  
                        System.out.println(msg);  
                    }  
                    else{  
                        editText.setText("data error");  
                    }  
                    out.close();  
                    in.close();  
                } catch (UnknownHostException e) {  
                    e.printStackTrace();  
                } catch (IOException e) {  
                    e.printStackTrace();  
                }  
                finally{  
                    try {  
                        if (null != socket){  
                            socket.close();  
                        }  
                    } catch (IOException e) {  
                        e.printStackTrace();  
                    }  
                }  
            }  
        });  
    }  
}  

 

应用完成后一定要记得释放Socket对象

1 public static void Close() throws IOException{
2         if(client!=null){
3              client.close();
4          }
5 }

2.http通信:http通信有两种实现方式,并且都有两种请求方式--get请求和post请求

 HttpURLConnection的get请求:get一般用来请求url地址,一次请求一次响应,返回结果后就关闭连接

1 //get
2 public HttpURLConnection urlconn= null
3 URL url = new URL(urlStr);
4 //打开一个URL所指向的Connection对象
5 urlconn = (HttpURLConnection)url.openConnection();
6 String result = StreamDeal(urlconn.getInputStream());
7 urlconn.disconnect();

HttpURLConnection的post请求:post请求一般用于提交某些数据表单,所以使用POST时,就需要使用setRequestMothod()来设置请求方式了

      URL url = new URL(urlStr);
        //打开一个URL所指向的Connection对象
         urlconn = (HttpURLConnection)url.openConnection();
    //设置该URLConnection可读
        urlconn.setDoInput(true);
         //设置该URLConnection可写
        urlconn.setDoOutput(true);
         //使用POST方式来提交数据
        urlconn.setRequestMethod("POST");
         //不运行缓存
         urlconn.setUseCaches(false);
        //当使用POST方式进行数据请求时,我们可以手动执行connect动作,当然,这个动作其实在getOutputStream()方法中会默认执行的
 //上面那些设置URLConnection属性的动作,一定要在connect动作执行前,因为一旦动作已经执行,熟悉设置就没有任何作用了
         urlconn.connect();
         //使用POST方式时,我们需要自己构造部分Http请求的内容,因此我们需要使用OutputStream来进行数据写如操作
        OutputStreamWriter writer = new OutputStreamWriter(urlconn.getOutputStream());
         
        String urlQueryStr = key+"="+URLEncoder.encode(value, "Utf-8");
        writer.write(urlQueryStr);
         
         writer.flush();
         writer.close();
        //获取返回的内容
         String result = StreamDeal(urlconn.getInputStream());

HTTPClient的get方式:

public String HttpGetMethod()
    {
        String result = "";
        try
        {
        HttpGet httpRequest = new HttpGet(urlStr);
        HttpClient httpClient = new DefaultHttpClient();
        HttpResponse httpResponse = httpClient.execute(httpRequest);
        if(httpResponse.getStatusLine().getStatusCode()==HttpStatus.SC_OK)
        {
            result = EntityUtils.toString(httpResponse.getEntity());
        }
        else
        {
            result = "null";
        }
        return result;
        }
        catch(Exception e)
        {
            return null;
        }
    }

HTTPClient的post请求:当我们使用POST方式时,我们可以使用HttpPost类来进行操作。当获取了HttpPost对象后,我们就需要向这个请求体传入键值对,这个键值对我们可以使用NameValuePair对象来进行构造,然后再使用HttpRequest对象最终构造我们的请求体,最后使用HttpClient的execute方法来发送我们的请求,并在得到响应后返回一个HttpResponse对象。其他操作和我们在HttpGet对象中的操作一样。

public String HttpPostMethod(String key,String value)
    {
        String result = "";
        try
        {
        // HttpPost连接对象
        HttpPost httpRequest = new HttpPost(urlStr);
        // 使用NameValuePair来保存要传递的Post参数
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        // 添加要传递的参数
        params.add(new BasicNameValuePair(key, value));
        // 设置字符集
        HttpEntity httpentity = new UrlEncodedFormEntity(params, "Utf-8");
        // 请求httpRequest
        httpRequest.setEntity(httpentity);
        // 取得默认的HttpClient
        HttpClient httpclient = new DefaultHttpClient();
        // 取得HttpResponse
        HttpResponse httpResponse = httpclient.execute(httpRequest);
        // HttpStatus.SC_OK表示连接成功
        if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            // 取得返回的字符串
            result = EntityUtils.toString(httpResponse.getEntity());
            return result; 
        } else {
             return "null";
        }
        }
        catch(Exception e)
        {
            return null;
        }
    }

 

 

 

 

 

 

 

posted @ 2018-03-06 15:38  阿苍老师  阅读(253)  评论(0编辑  收藏  举报