zoukankan      html  css  js  c++  java
  • 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()+ "
    " ;  
                    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;
            }
        }

     

  • 相关阅读:
    考试中一元三次方程的解法
    变限积分求导公式--加上自己理解
    柯西中值定理
    sec x的积分及注意事项
    线性代数
    IntelliJ IDEA无法新建类解决办法
    idea中Server returns invalid timezone. Go to 'Advanced' tab and set 'serverTimezone' property manually.
    Windows 64位下安装Redis 以及 可视化工具Redis Desktop Manager的安装和使用
    使用@Param注解
    关于在方法里面使用泛型public static <T> T
  • 原文地址:https://www.cnblogs.com/nullering/p/7898512.html
Copyright © 2011-2022 走看看