Android HttPUrlConnection



  • GET和POST方式有什么区别
  • HttPUrlConnection请求网络数据实例
  • HttPUrlConnection加载网络数据实例
  • String/StringBuffer/StringBuilder有什么区别

    GET和POST方式有什么区别

    get方法属于明文传参,在地址栏可以看到参数调用简单,不安全。post方法属于暗文传参,在地址栏参数不可见,调用复杂,安全。

    post请求使用方法

new Thread(new Runnable() {
    @Override
    public void run() {
        try {
            URL url = new URL(getUrl);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("POST");//设置请求方式为POST
            connection.setDoOutput(true);//允许写出
            connection.setDoInput(true);//允许读入
            connection.setUseCaches(false);//不使用缓存
            connection.connect();//连接
            int responseCode = connection.getResponseCode();
            if(responseCode == HttpURLConnection.HTTP_OK){
                InputStream inputStream = connection.getInputStream();
                String result = is2String(inputStream);//将流转换为字符串。
                Log.d("kwwl","result============="+result);
            }

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

get请求的使用方法

HttpURLconnection是同步的请求,所以必须放在子线程中。使用示例如下:

new Thread(new Runnable() {
    @Override
    public void run() {
        try {
            String url = "https://www.baidu.com/";
            URL url = new URL(url);
            //得到connection对象。
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            //设置请求方式
            connection.setRequestMethod("GET");
            //连接
            connection.connect();
            //得到响应码
            int responseCode = connection.getResponseCode();
            if(responseCode == HttpURLConnection.HTTP_OK){
                //得到响应流
                InputStream inputStream = connection.getInputStream();
                //将响应流转换成字符串
                String result = is2String(inputStream);//将流转换为字符串。
                Log.d("kwwl","result============="+result);
            }

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

get请求的使用方法如上。如果需要传递参数,则直接把参数拼接到url后面,其他完全相同,如下:

String url = "https://www.baidu.com/?userName=zhangsan&password=123456";

注意点:
1,url与参数之间用?隔开。
2,键值对中键与值用=连接。
3,两个键值对之间用&连接。

分析:
1, 使用connection.setRequestMethod(“GET”);设置请求方式。
2, 使用connection.connect();连接网络。请求行,请求头的设置必须放在网络连接前。
3, connection.getInputStream()只是得到一个流对象,并不是数据,不过我们可以从流中读出数据,从流中读取数据的操作必须放在子线程。
4, connection.getInputStream()得到一个流对象,从这个流对象中只能读取一次数据,第二次读取时将会得到空数据。

HttPUrlConnection请求网络数据实例

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".WebActivity">
    <Button  android:id="@+id/btn" android:layout_width="match_parent" android:layout_height="30dp" />

LinearLayout>
public class WebActivity extends Activity {
    private Button button;


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

        button=findViewById(R.id.btn);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        getWebInfo();
                    }
                }).start();
            }
        });


    }
    private void getWebInfo(){
        try {
            URL url = new URL("https://www.baidu.com");
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            InputStream inputStream = connection.getInputStream();
            InputStreamReader reader=new InputStreamReader(inputStream);
            BufferedReader bufferedReader = new BufferedReader(reader);
            String temp = "";
            StringBuffer stringBuffer = new StringBuffer();
            while ((temp = bufferedReader.readLine())!=null){
                stringBuffer.append(temp);
            }
            Log.e("******",stringBuffer.toString());

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

HttPUrlConnection加载网络数据实例

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity" >

    <ImageView  android:id="@+id/iv" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1" />

    <EditText  android:id="@+id/et_path" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="请输入图片路径" android:text="http://b.hiphotos.baidu.com/image/w%3D310/sign=a439f5b24510b912bfc1f0fff3fdfcb5/83025aafa40f4bfb92c52c5d014f78f0f73618a5.jpg" android:maxLines="1" />

    <Button  android:layout_width="fill_parent" android:layout_height="wrap_content" android:onClick="click" android:text="浏览" />

LinearLayout>
public class MainActivity extends AppCompatActivity {

    protected static final int CHANGE_UI = 1;
    protected static final int ERROR = 2;
    private EditText et_path;
    private ImageView iv;
    // 主线程创建消息处理器
    private Handler handler = new Handler(){
        public void handleMessage(android.os.Message msg) {
            if(msg.what == CHANGE_UI){
                Bitmap bitmap = (Bitmap) msg.obj;
                iv.setImageBitmap(bitmap);
            }else if(msg.what == ERROR){
                Toast.makeText(MainActivity.this, "显示图片错误", 0).show();
            }
        };
    };
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        et_path = (EditText) findViewById(R.id.et_path);
        iv = (ImageView) findViewById(R.id.iv);
    }
    public void click(View view) {
        final String path = et_path.getText().toString().trim();
        if (TextUtils.isEmpty(path)) {
            Toast.makeText(this, "图片路径不能为空", Toast.LENGTH_SHORT).show();
        } else {
            //子线程请求网络,Android4.0以后访问网络不能放在主线程中
            new Thread() {
                public void run() {
                    // 连接服务器 get 请求 获取图片.
                    try {
                        URL url = new URL(path);       //创建URL对象
                        // 根据url 发送 http的请求.
                        HttpURLConnection conn = (HttpURLConnection) url
                                .openConnection();
                        // 设置请求的方式
                        conn.setRequestMethod("GET");
                        //设置超时时间
                        conn.setConnectTimeout(5000);
                        // 得到服务器返回的响应码
                        int code = conn.getResponseCode();
                        //请求网络成功后返回码是200
                        if (code == 200) {
                            //获取输入流
                            InputStream is = conn.getInputStream();
                            //将流转换成Bitmap对象
                            Bitmap bitmap = BitmapFactory.decodeStream(is);
                            //iv.setImageBitmap(bitmap);
                            //TODO: 告诉主线程一个消息:帮我更改界面。内容:bitmap
                            Message msg = new Message();
                            msg.what = CHANGE_UI;
                            msg.obj = bitmap;
                            handler.sendMessage(msg);
                        } else {
                            //返回码不是200 请求服务器失败
                            Message msg = new Message();
                            msg.what = ERROR;
                            handler.sendMessage(msg);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        Message msg = new Message();
                        msg.what = ERROR;
                        handler.sendMessage(msg);
                    }
                };
            }.start();
        }
    }

}

String/StringBuffer/StringBuilder有什么区别

 1.三者在执行速度方面的比较:StringBuilder > StringBuffer > String
 
 2.String <(StringBuffer,StringBuilder)的原因

    String:字符串常量

    StringBuffer:字符创变量

    StringBuilder:字符创变量

    从上面的名字可以看到,String是“字符创常量”,也就是不可改变的对象。对于这句话的理解你可能会产生这样一个疑问 ,比如这段代码:
    

 String s = "abcd";
 s = s+1;
 System.out.print(s);// result : abcd1

我们明明就是改变了String型的变量s的,为什么说是没有改变呢? 其实这是一种欺骗,JVM是这样解析这段代码的:首先创建对象s,赋予一个abcd,然后再创建一个新的对象s用来执行第二行代码,也就是说我们之前对象s并没有变化,所以我们说String类型是不可改变的对象了,由于这种机制,每当用String操作字符串时,实际上是在不断的创建新的对象,而原来的对象就会变为垃圾被GC回收掉,可想而知这样执行效率会有多底。

  • 但是在一种特殊情况下string运行速度居然超过了stringBuilder:
String str = “This is only a” + “ simple” + “ test”;
StringBuffer builder = new StringBuilder(“This is only a”).append(“simple”).append(“ test”);

你会很惊讶的发现,生成str对象的速度简直太快了,而这个时候StringBuffer居然速度上根本一点都不占优势。其实这是JVM的一个把戏,实际上:

    String str = “This is only a” + “ simple” + “test”;

    其实就是:

    String str = “This is only a simple test”;

    所以不需要太多的时间了。但大家这里要注意的是,如果你的字符串是来自另外的String对象的话,速度就没那么快了,譬如:

    String str2 = “This is only a”;

    String str3 = “ simple”;

    String str4 = “ test”;

    String str1 = str2 +str3 + str4;

    这时候JVM会规规矩矩的按照原来的方式去做。

3.StringBuilder与 StringBuffer:

    StringBuilder:线程非安全的

    StringBuffer:线程安全的

    当我们在字符串缓冲去被多个线程使用是,JVM不能保证StringBuilder的操作是安全的,虽然他的速度最快,但是可以保证StringBuffer是可以正确操作的。当然大多数情况下就是我们是在单线程下进行的操作,所以大多数情况下是建议用StringBuilder而不用StringBuffer的,就是速度的原因。

对于三者使用的总结:

   1.如果要操作少量的数据用 = String  

   2.单线程操作字符串缓冲区 下操作大量数据 = StringBuilder

   3.多线程操作字符串缓冲区 下操作大量数据 = StringBuffer