安卓基础总结 网络基础 Connector post get

1.URLConnection

用于获取网络连接的接口,我们常用它的实现类HttpURLConnection设置网络连接信息。

API

//通过一个URL对象
URL url = new URL(path);

//获取openConnection,用于对连接进行设置
HttpURLConnection openConnection = (HttpURLConnection)url.openConnection();

//设置请求方式
openConnection.setRequestMethod("GET");
//设置超时时间
openConnection.setConnectTimeout(5000);

例程 查看网页源码

进行网络操作不可以在主线程中,所以需要另外开一个线程。

操作UI相关只能在主线程中,所以需要在子线程中调用runOnUiThread操作前面板控件,或者使用消息机制

1、发送请求
(1)创建一个URL对象
(2)设置请求头信息

2、服务器返回数据
(1)判断状态码:200 ok,404 没有找到资源、503、509 服务器端错误
(2)解析服务器返回的二进制数据,解析成一个图片
(3)把图片显示在TextView上

public void click(View v)
{
    new Thread(new Runnable() {

        @Override
        public void run() {

            try {
                //获取路径
                path = et_path.getText().toString().trim();
                URL url = new URL(path);
                HttpURLConnection openConnection = (HttpURLConnection)url.openConnection();
                openConnection.setRequestMethod("GET");
                openConnection.setConnectTimeout(5000);

                //获取返回码
                int responseCode = openConnection.getResponseCode();
                if(responseCode == 200)  //返回成功
                {
                    InputStream in = openConnection.getInputStream();

                    final String str = StreamUtils.ReadStream(in);

                    System.out.println(str+"+++++++++++");

                    //将显示信息放到主线程
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            //设置显示控件显示源码信息
                             tv_content.setText(str);
                        }
                    });
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }).start();
}

//用于从网络中读取数据
public static String ReadStream(InputStream in) throws IOException
{
    ByteArrayOutputStream baos = new ByteArrayOutputStream();

    byte buf[] = new byte[1024];
    int len = 0;

    while((len=in.read(buf)) != -1)
    {
        baos.write(buf, 0, len);
    }

    return baos.toString();
}

2.Handler 与 消息机制

消息机制可以用来进行主线程与子线程间的通信,由于子线程不能操作显示控件,我们可以把一些信息放到消息中,主线程收到消息后对控件进行操作

API

在主线程创建的时候注册一个消息handler,重写handleMessage方法,对消息的内容进行处理。

主线程

  handler = new Handler(){
  @Override
  public void handleMessage(Message msg) {
        uper.handleMessage(msg);

        //这里是收到消息,获取消息的内容
        tv_content.setText((String)msg.obj);
    }
 };

子线程

//获取一个msg
Message msg = Message.obtain();
//设置msg携带的信息
msg.obj = str;
//发送这个信息给主线程中注册的    Handler(){              
handler.sendMessage(msg);

例程: 读取网络上的位图

BitmapFactory.decodeStream(in); 将流转换为bitmap

msg.what = 1; 设置msg中携带的数字消息

1、创建URL,打开一个HTTP的连接;
2、设置请求头信息:GET(GET、POST)
3、接收服务器端返回的响应数据,响应码:200 ok,404没有找到资源 ,503服务器端内部错误
4、把接收的二进制数据转换成图片

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    et_path = (EditText) findViewById(R.id.et_path);

    final ImageView iv_img = (ImageView) findViewById(R.id.iv_img);

    handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            //获取msg 并判断msg的类型
            int statu  = msg.what;
            if(statu == 1)
            {
                //在主线设置显示bitmap
                iv_img.setImageBitmap(bitmap);
            }
        }
    };
}


public void click(View v)
{
    new Thread(new Runnable() {

        @Override
        public void run() {

            try {
                //获取路径
                path = et_path.getText().toString().trim();
                URL url = new URL(path);
                HttpURLConnection openConnection = (HttpURLConnection)url.openConnection();
                openConnection.setRequestMethod("GET");
                openConnection.setConnectTimeout(5000);

                //获取返回码
                int responseCode = openConnection.getResponseCode();
                if(responseCode == 200)  //返回成功
                {
                    //获取网络上响应的数据流
                    InputStream in = openConnection.getInputStream();
                    //使用BitmapFactory将数据流转换为bitmap
                    bitmap = BitmapFactory.decodeStream(in);
                    //设置msg的信息
                    Message msg = Message.obtain();
                    msg.what = 1;
                    //发送msg给主线程
                    handler.sendMessage(msg);
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }).start();
}   

3.消息机制常用API

API

1.runOnUiThread 在子线程中操作UI使用的函数

new Thread(){public void run() {

    //Android系统 底层 有一个审计机制  在开发中 都使用 Handler  审计机制启动需要时间,启动后如果在子线程中直接操作显示控件,就会报 
    //  try {
    //      Thread.sleep(100);
    //  } catch (InterruptedException e) {
    //      e.printStackTrace();
    //  }

        //这个方法最终都会在ui线程中执行 
        runOnUiThread( new Runnable() {
            public void run() {
                tv.setText("哈哈 我更新了ui");
            }
        });


    };}.start();

2.Handler().postDelayed 多少毫秒后开始执行run方法

    new Handler().postDelayed(new Runnable() {

        @Override
        public void run() {
            //5秒钟之后执行 run方法 
            tv.setText("haha");

        }
    }, 5000);

3.另外一个定时执行函数的方法Timer

    //回顾Timer的使用 
    Timer timer = new Timer(); //创建一个定时器 
    TimerTask task = new TimerTask() {

        @Override
        public void run() {
            System.out.println("haha");
        }
    };
    //5 秒钟后 执行 run方法 
    //5秒后 执行run方法 在每隔2秒钟在执行一次 run方法 
    timer.schedule(task, 5000,2000);

4.模拟一个第一次启动弹出广告页面的程序

1.功能需要使用上一个条目的知识,在一定的时间后调用某个指定的函数

2.需要知道如何切换到另外一个页面

API 切换页面

1.class MainActivity2 extends Activity    //建立一个类,继承Activity
2.onCreate 中设置要加载的页面布局文件setContentView(R.layout.activity_main2);
3.在清单文件中配置布局文件
 <activity android:name="com.example.myweixinstartup.MainActivity2"></activity>

4.Intent intent = new Intent(MainActivity.this, MainActivity2.class);       //用Intent加载这个新的页面
5.startActivity(intent);

API 延迟加载

        new Handler().postDelayed(new Runnable() {

            @Override
            public void run() {
                Intent intent = new Intent(MainActivity.this, MainActivity2.class);
                startActivity(intent);
            }
        }, 3000);

5.新闻客户端界面显示

1.创建的时候,需要连接服务器,获取新闻信息(XML文件)
2.解析XML文件,封装相关条目(Item),存入一个List返回该List
3.将条目依次显示到ListView中

*图片资源在XML中存放一个URL地址,可以使用SmartImageView(开源项目)作为图片的类替代ImageView,SmartImageView中提供了直接从URL中获取图片资源的方法。

主程序

先考虑两个问题

1.List文件如何将条目显示到ListView中?

在getView方法中通过positon作为List的索引。

2.ListView在哪里设置显示?

注意,使用网络操作,获取xml文件,是在一个子线程中进行的。这样,如果我们把显示xml信息的方法直接放在主线程中,那么就可能在没有获取List信息的情况下
就执行了显示ListView的方法。所以,应该把显示操作放在

public class MainActivity extends Activity {

private List<NewsItem> itemLists;
private ListView listView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    listView = (ListView)findViewById(R.id.lv);

    init();     
} 

public void init()
{
    final String path="http://192.168.19.114/news/news.xml";
    new Thread(){

        public void run() {
            try {
                URL url = new URL(path);
                HttpURLConnection openConnection = (HttpURLConnection) url.openConnection();
                openConnection.setReadTimeout(5000);
                openConnection.setRequestMethod("POST");

                int type = openConnection.getResponseCode();
                if(type == 200)
                {
                    InputStream is = openConnection.getInputStream();                       
                    itemLists = XMLUtiles.getItems(is);                 
                }

                //由于xml中的信息是在子线程中获取的,如果显示直接放到主线程,则不能保证在显示时已经获取到xml的数据
                runOnUiThread(new Runnable() {                      
                    @Override
                    public void run() {
                        listView.setAdapter(new MyAdaptor());
                    }
                });

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }.start();
}

class MyAdaptor extends BaseAdapter {

    @Override
    public int getCount() {

        return itemLists.size();
    }

    @Override
    public Object getItem(int position) {

        return null;
    }

    @Override
    public long getItemId(int position) {

        return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        View view = null;

        if(convertView == null){
            view = View.inflate(getApplicationContext(), R.layout.item, null);
        }else{
            view = convertView;
        }

        //使用position参数作为List的索引
        NewsItem newsItem = itemLists.get(position);

        TextView tv_title = (TextView)view.findViewById(R.id.tv_title);
        TextView tv_content = (TextView)view.findViewById(R.id.tv_content);
        TextView tv_type = (TextView)view.findViewById(R.id.tv_type);

        SmartImageView tv_image = (SmartImageView) view.findViewById(R.id.tv_image);

        tv_title.setText(newsItem.getTitle());
        tv_content.setText(newsItem.getDescription());
        tv_type.setText(newsItem.getType());

        tv_image.setImageUrl(newsItem.getImage());

        return view;
    }
}
}

6.用户登录

使用get方法提交数据

public void click(View v)
{

    final String username = et_username.getText().toString().trim();
    final String password = et_password.getText().toString().trim();

    new Thread(){
        public void run() {
            //将数据直接写到url中
            String pathString = "http://192.168.19.114/web/LoginServlet?username="+username+"&password="+password;
            try {
                URL url = new URL(pathString);
                HttpURLConnection conn = (HttpURLConnection)url.openConnection();
                conn.setRequestMethod("GET");
                conn.setConnectTimeout(5000);

                int code = conn.getResponseCode();
                if(code == 200)
                {
                    InputStream in = conn.getInputStream();
                    String retStr = StreamUtils.ReadStream(in);

                    showToast(retStr);
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        };
    }.start();      

}

使用post方法提交数据

public void click1(View v)
{

    final String username = et_username.getText().toString().trim();
    final String password = et_password.getText().toString().trim();

    new Thread(){
        public void run() {
            String pathString = "http://192.168.19.114/web/LoginServlet";
            try {
                //创建URL对象
                URL url = new URL(pathString);
                //打开一个URL连接
                HttpURLConnection conn = (HttpURLConnection)url.openConnection();
                //设置请求方式  POST字符串需要大写
                conn.setRequestMethod("POST");
                //设置超时时间
                conn.setConnectTimeout(5000);

                //数据为键值对
                String data = "username="+username+"&password="+password;

                //设置请求头信息,下面的用于post请求
                conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
                conn.setRequestProperty("Content-Length", data.length()+"");

                // 设置一个标记 允许像服务器输出 
                conn.setDoOutput(true);
                //把数据写到输出流中进行输出操作
                conn.getOutputStream().write(data.getBytes());

                int code = conn.getResponseCode();
                if(code == 200)
                {
                    InputStream in = conn.getInputStream();
                    String retStr = StreamUtils.ReadStream(in);

                    showToast(retStr);
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        };
    }.start();      

}

弹出土司,由于在网络子线程中,所以可以将土司封装一下

public void showToast(final String str)
{
    runOnUiThread(new Runnable() {          
        @Override
        public void run() {
            Toast.makeText(getApplicationContext(), str, Toast.LENGTH_LONG).show();
        }
    });
}

读取网络流工具包

public class StreamUtils {

public static String ReadStream(InputStream in) throws IOException
{
    ByteArrayOutputStream baos = new ByteArrayOutputStream();

    byte buf[] = new byte[1024];
    int len = 0;

    while((len=in.read(buf)) != -1)
    {
        baos.write(buf, 0, len);
    }

    return baos.toString("gbk");
}
}

你可能感兴趣的:(安卓)