Quantcast
Channel: CSDN博客移动开发推荐文章
Viewing all 5930 articles
Browse latest View live

Java学习笔记之Swing(一)

$
0
0

Java学习笔记之Swing(一)


学习目标

  • 了解Swing的基本开发过程。
  • 掌握如何创建窗口、面板、标签和按钮。
  • 掌握和熟练使用Swing中的事件。

Swing的第一个程序

import javax.swing.*;
public class Swing1 extends JFrame{
 public Swing1 {
    this.setLayout(null);//设置布局管理器
    JLabel jl=new JLabel();//定义一个标签
    jl.setText("第一个Swing程序"); //设置显示的文字 
    jl.setBounds(50,50,400,50); //设 置标签的大小和位置 
    this.add(jl); //将标签放到窗口中    
    this.setBounds(300,250,500,200); //设置窗口的大小和位置 
    this.setVisible(true); //设置窗口是可见的
 }
 public static void main(String args[]){
    Swing1 s=new Swing1();
 }
}

JFrame窗口类简介

在开发Swing程序中,通常是通过继承JFrame类来实现窗口的。在该类中具有包括定义窗口标题、标框,以及窗口的 大小和位置等众多方法。在介绍这些方法之前,先来介绍一下JFrame窗口类的构造器。JFrame窗口类具有四种构造器。

最常用的JFrame窗口类的构造器是无参构造器,使用该构造器将创建一 个初始不可见的新窗体。除此之外还有具有一个String类参数的构造器,使用该构造器能够在初始时就创建一个具有标题的新窗体。还有两种 需要给出图形配置参数的构造器,这两种构造器此处不进行介绍。

创建新窗口后,就可以通过JFrame窗口类的方法来设置新窗口。首先使 用无参构造器创建的是一个不可见的新窗体,所以要使用方法来将窗体 设置为可见的形式。在JFrame窗口类中定义了一个setVisible方法来设 置窗口的可见性,该方法具有一个布尔型参数,true表示可见,false表 示不可见。将初始状态下的窗口设置为不可见是有原因的,因为有很多 对窗口的操作需要在窗口不可见的状态下执行,从而setVisible方法通 过在程序的最后执行。

在JFrame窗口类中有个setTitle方法,该方法需要一个字符型参 数。使用setTitle方法可以设置窗口的名称;还有一个setBounds方法,该方法具有4个参数,前两个参数分别表示窗口位置的横坐标和纵坐标,后两个参数分别表示窗口大小的宽度和高度。 JFrame窗口类最重要的方法就是add方法,使用该方法可以将组 件添加到窗口中。除此之外,该类中常用的方法还有setResizable,使用该方法可是设置窗口是否允许调整大小。

JFrame类中还有一个重要的方法,即setDefaultCloseOperation.使用该方法可是设置单击关闭窗口时执行的动作。这里的动作包括四种情况:

  • DO_NOTHING_ON_CLOSE:不执行任何动作;
  • DIPOSE_ON_CLOSE:释放窗体对象;
  • HIDE_ON_CLOSE: 隐藏窗体;
  • EXIT_ON_CLOSE: 退出JVM。

    注意:如果不对该值进行设置,默认的值为HIDE_ON_CLOSE,也就是默认情况下单击关闭按钮会隐藏窗口。

JPanel类

JPnael类与上面的JFrame类一样,都属于一个容器类。在正式介绍该类之前我们需要先介绍一下什么是容器。

Swing中的控件可以分为三类,顶层容器、非顶层容器和普通控件。JFrame就属于一个顶层容器。顶层容器是一种可以直接显示在系统桌面的控件,其他控件必须直接或间接的借助顶层容器来显示。顶层容器除了包括JFrame类外,还包括JWindow类和JDialog类。

JPnael类属于一个非顶层容器类。非顶层容器具有两面性,非顶层容器需要放到顶层容器中使用,对于顶层容器来说,非顶层容器只是属于一般的控件。当我们在非顶层容器中添加控件时,对这些控件而言,非顶层容器就属于一个容器。

JPnael面板类简介

JPanel类是一个非顶层容器类,它具有四种构造器,最常用的依然是无参构造器,使用有参构造器可以设置面板使用什么样的布局管理器和是否使用双缓冲。JPanel面板类具有一个添加控件的add方法,使用该方法可以将普通控件添加到面板中。getHeightgetWidth方法可以返回当前面板的高度和宽度。JPanel类中还有一个重要的setToolTipText方法,该方法具有一个字符串参数,该方法的作用是当鼠标指针停在面板上时显示文本内容,字符串指定的就是所要显示的文本。

JLabel标签类

标签是Swing中最基本的控件,它是一种非交互式的控件。JLabel有六个构造器:

标签构造器 说明
public void JLabel() 创建没有图像和标题的标签
public void JLabel(Icon image) 创建具有图像的标签
public void JLabel(Icon image,int horizontalAlignment) 创建具有图像和指定对齐方式的标签
public void JLanel(String text) 创建指定文本的标签
public void JLable(String text,int horizontalAlignment) 创建指定文本和指定对齐方式的标签
public void JLabel(String text,Icon image,int horizontalAlignment) 创建指定文本、图像和指定对齐方式的标签

创建一个标签的程序如下:

    import javax.swing.*;
    //继承JFrame类
    public class Swing8 extends JFrame
    JLabel jl=new JLabel(); //定义构造器
    public Swing8()
    {
    this.setTitle("创建标签");
    jl.setText("这是一个标签"); jl.setVerticalAlignment(JLabel.CENTER);//设置标签垂直居中 
    jl.setHorizontalAlignment(JLabel.CENTER);//设置标签水平居中 
    this.add(jl); //将标签添加到窗口中   
    this.setBounds(300,250,300,200); //设置窗口的大小和位置 
    this.setVisible(true); //设置窗口是可见的
    }
    public static void main(String args[]) {
    Swing8 s=new Swing8();
    }

运行结果:

这里写图片描述

JButton按钮类

JButton类也有多个构造器,最常用的依然是无参构造器。在JButton按钮类中具有几个很常用的方法。其中setText方法是 来设置按钮上显示的文本,和其对应的是用getText方法来获取按 钮上显示的文本。在JButton按钮类中还有一个经常被使用,即setMnemonic方法,使用该方法可以设置按钮的助记符。助记符就是使用键盘中的Alt加该助记符就能起到相应的功能。

创建一个简单按钮的实例如下:

     import javax.swing.*;
    //继承JFrame类
     public class Swing9 extends JFrame
    {
    JButton jb=new JButton(); //定义构造器
    public Swing9()
    {
    this.setTitle("创建按钮");
    jb.setText("这是一个按钮"); //设置按钮上显示的内容 
    jb.setMnemonic('a'); //设置按钮的助记符 
    this.add(jb); //将按钮添加到窗口中 
    this.setBounds(300,250,300,200); //设置窗口的大小和位置 
    this.setVisible(true); //设置窗口是可见的
    }
    public static void main(String args[]) {
    Swing9 s=new Swing9();
    }

编译运行上面的实例代码之后,创建出一个窗口,整个窗口中只有一个按钮,而且按钮沾满了整个窗口。当我们从键盘上按下Alt+A组合键时相当于点击了这个按钮。这就是助记符的作用。

Swing中的事件

事件是一种很好的用户和界面的交互手段。在事件的发生和响应的过程中需要两个对象,事件监听器和事件源。事件源就是我们常见的一些可交互的控件,例如按钮、文本框和窗口等。但是不同的控件是存在不同的事件的,事件信息被封装在事件对象 中。事件监听器是指实现专门的监听接口的类的对象。每一个事件都有 对应的监听接口,同时在该接口中给出了处理事件的方法。在编写监听 器时需要事件监听接口,同时实现其中的方法,在方法中编写触发事件 后执行的程序。在编写程序时,还需要将监听器注册给事件源,这样才能执行事件。

同一个事件源注册多个监听器:

同一个事件源可以同时注册多个监听器,这种情况下触发事件, 所有的监听器都将执行事件方法,对事件进行处理。
当为同一个事件源注册多个监听器时,监听器的执行顺序并不是 先注册先执行的顺序,而是先注册后执行的顺序来执行的。

实例代码:
import javax.swing.*;
public class Swing5 extends JFrame{
    JButton jb=new JButton();
    int i=0;//按钮被单击的次数
    public Swing5(){
        this.setTitle("创建按钮");
        jb.setText("按钮按下了0次");
        jb.setMnemonic('a');
        this.add(jb);
        //为按钮注册监听器
        jb.addActionListener(new ActionListener() {
            //触发事件时执行的方法
            public void actionPerformed(ActionEvent e){
            Swing5.this.jb.setText("按钮按下了"+(++i)+"次");
            }
        });
        //为按钮注册第二个监听器
        jb.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e){
            Swing5.this.jb.setText("按钮按下了"+(++i)+"次");
            }

    });
        this.setBounds(100,200,300,250);
        this.setVisible(true);
}
public static void main(String args[]){
    Swing5 s=new Swing5();
}
}

同一个监听器注册给多个事件源

同一个监听器注册给多个事件源的情况下,所有的事件源中的任 意一个触发事件都会通知监听器,并执行监听器中的事件处理方法。将一个监听器注册给多个事件源,从而不管是单击哪一个按钮,都将执行监听器方法。为了辨别是哪一个按钮被按下,在监听器方法中需要判断是哪一个按钮触发了事件,执行的效果是使另一个按钮的显示内容发生变化。

窗体获取和失去焦点事件

窗体中的所有事件都是使用WindowEvent类来表示。窗体获取和失去焦点事件,该事件是通过实现 WindowFocusListener监听接口实现的。

窗体打开、关闭和激活事件

要实现窗体打开、关闭和激活事件只需要实现WindowListener监听接口的监听器。

按钮事件

按钮时具有事件的,当我们单击按钮时就出发了按钮事件,即ActionEvent事件。如果我们希望按钮事件触发后执行我们指定的程序,我们需要为按钮添加动作事件监听器,并且需要为按钮注册动作事件监听器。编写动作事件监听器需要通过实现ActionListener监听接口来完成。

在ActionListener监听接口中只有一个actionPerformed方法,所以在动作事件监听器中只需要实现这个方法。我们可以将触发事件后需要执行的程序写在actionPerformed方法中。定义完监听器后,我们还需要向按钮注册该监听器,注册监听器可以通过addActionListener方法来完成。

作者:Felix_Smile 发表于2016/9/16 20:28:41 原文链接
阅读:82 评论:0 查看评论

Android 浅谈 Activity(下)

$
0
0

上篇内容讲一些比较基本和简单的用法,这篇稍微说一些相对来来说比较高级一点的用法。

数据传递

举例来讲:当前页面上有一个EditText用于接收用户输入信息,当点击一个按钮,开启下一个页面,并在写个页面显示用户所输入的文字,怎么做?
这就涉及到了Activity之间数据传递。
而通过Intent就可以做到这个功能,查看官方API发现Intent有一个putExtra的方法,接收很多种数据类型,如图:
这里写图片描述
接收的参数其实是以key,value的形式,第一个参数接收一个String字符串,第二个参数代表要传递的数据类型。在Activity之间传输的数据类型有基本类型、数组、Bundle、Serializable对象、Parcelable对象等。
话不多说,上代码。

package com.mesmerize.activitytest;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

/**
 * Created by mesmerize on 16/9/16.
 */
public class InputActivity extends Activity implements View.OnClickListener {

    private EditText et_input;
    private String inputContent;
    private Button btn_click;

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

        initView();
        initListener();
    }

    /**
     * 初始化View控件
     */
    private void initView() {

        et_input = (EditText) findViewById(R.id.et_input);
        btn_click = (Button) findViewById(R.id.btn_click);
    }

    /**
     * 获取用户输入的文字信息
     */
    private void fillData() {

        inputContent = et_input.getText().toString();
    }

    private void initListener() {

        btn_click.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {

        switch (v.getId()) {

            case R.id.btn_click:

                skipActivity();
                break;
        }
    }

    private void skipActivity() {

        fillData();

        Intent intent = new Intent(InputActivity.this,AcceptActivity.class);
        intent.putExtra("transfer", inputContent);
        startActivity(intent);
    }
}

xml文件没什么可说的,就一个TextView一个EditText还有一个Button
这里写图片描述

当我输入“Hello Activity”
这里写图片描述

这个时候我点击按钮会执行skipActivity() 这个方法,可以看到我给intent塞了一条数据

接下来看AcceptActivity的代码:

package com.mesmerize.activitytest;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

/**
 * Created by mesmerize on 16/9/16.
 */
public class AcceptActivity extends Activity {

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

        String data = getData();
        TextView tv_accept = (TextView) findViewById(R.id.tv_accept);

        tv_accept.setText(data);
    }

    /**
     * 获取上个页面传递过来的数据
     */
    private String getData() {
        // 注意,这个key千万不能写错,它是跟上个页面所写的key一一对应的
        String transfer = getIntent().getStringExtra("transfer");

        return transfer;
    }

}

其实这个代码很简单,就是获取上个页面intent里传过来的一个key的名为“transfer”的数据,取到这个数据之后放入TextView里面展示出来。
这是一个结果

除了传递String,还可以传很多很多的类型

    Intent intent = new Intent(this, 目标Activity.class);
    Bundle b1 = new Bundle();
    b1.putString("name", "亚索");
    b1.putInt("age", 25);
    Bundle b2 = new Bundle();
    b2.putString("name", "劫");
    b2.putInt("age", 33);
    intent.putExtra("b1", b1);
    intent.putExtra("b2", b2);

    // 比如传递一个对象
    Intent intent = new Intent(this, 目标Activity.class);
    Person p = new Person("艾克", 44);
    intent.putExtra("p", p);

以上就是一个简单的数据传递的一个示例

数据回传

有些时候我们会遇到数据回传的需求,比如下订单时填写收货地址信息或者例如发帖子时要附带一些图片,进入图库选择好照片后,会返回到发表状态页面并带回所选的图片信息等等等等,这些在开发中是很常见的。而如果我们要实现这种需求该怎么做呢?
发现官方文档上有这么个介绍:

Sometimes, you might want to receive a result from the activity that you start. In that case, start the activity by calling startActivityForResult() (instead of startActivity()). To then receive the result from the subsequent activity, implement the onActivityResult() callback method. When the subsequent activity is done, it returns a result in an Intent to your onActivityResult() method.

原来启动Activity不仅仅只有一个startActivity(),还有一个启动的方式叫startActivityForResult()。
当要实现数据回传的时候可以利用startActivityForResult()这种方法来替代startActivity。还要实现onActivityResult()这个回调方法。
废话不多说,上代码:
这是第一个Activity
这里写图片描述

package com.mesmerize.activitytest;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

/**
 * Created by mesmerize on 16/9/16.
 */
public class FirstActivity extends Activity implements View.OnClickListener {

    private TextView tv_result;
    private Button btn_skip;

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

        initView();
        initListener();
    }

    /**
     * 初始化View控件
     */
    private void initView(){

        tv_result = (TextView) findViewById(R.id.tv_result);
        btn_skip = (Button) findViewById(R.id.btn_skip);
    }

    private void initListener(){

        btn_skip.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {

        switch (v.getId()){

            case R.id.btn_skip:

                skipActivity();
                break;
        }
    }

    /**
     * 开启下一个Activity
     */
    private void skipActivity(){

        Intent intent = new Intent(FirstActivity.this, SecondActivity.class);

        // param2 意味请求码,是一个int值
        startActivityForResult(intent,1);
    }


    /**
     * Activity数据的回传 为了拿到传回的数据  必须在源Activity中重写onActivityResult
     * @param requestCode  请求码  即调用startActivityForResult()传递过去的int值
     * @param resultCode   结果码  结果码用于标识返回数据来自哪个新Activity
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (data != null) {

            switch (requestCode) {

                case 1:

                    String result = data.getStringExtra("result");

                    tv_result.setText("回传的数据是: "+ result);
                    break;
            }
        }
    }
}

很简单,就是一个很简单的两个控件
看下一个Activity,当点击按钮开启一个新的Activity
这里写图片描述
代码如下:

package com.mesmerize.activitytest;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;


/**
 * Created by mesmerize on 16/9/16.
 */
public class SecondActivity extends Activity implements View.OnClickListener {

    private Button btn_finish;
    private EditText et_input;

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

        initView();
        initListener();
    }

    private void initView() {

        et_input = (EditText) findViewById(R.id.et_input);
        btn_finish = (Button) findViewById(R.id.btn_finish);
    }

    private void initListener() {

        btn_finish.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {

        switch (v.getId()) {

            case R.id.btn_finish:

                passbackResult();
                break;
        }
    }

    /**
     * 点击按钮,将输入的文字回传到上个Activity中去
     */
    private void passbackResult() {

        // 获取EditText中所输入的内容
        String content = et_input.getText().toString();

        // 数据使用Intent进行回传
        Intent intent = new Intent();

        // 将输入的内容放入intent中去
        intent.putExtra("result", content);

        // 设置返回数据 RESULT_OK是一个int值 除此之外 还有RESULT_CANCELED / RESULT_FIRST_USER
        setResult(RESULT_OK,intent);

        // 关闭当前Activity
        finish();

    }
}

当我输入一段文字之后,比如我输入“Ha SA Ki”,然后点击输入完毕,回传数据…
这里写图片描述

看代码就是:关闭当前Activity,并且把当前EditText上所输入的内容放到Intent中,返回给上一个Activity,即FirstActivity。
这里写图片描述

这个就是一个很简单的数据回传的示例。
讲一讲requestCode(请求码)和resultCode(结果码)的作用

requestCode 请求码

使用startActivityForResult(Intent intent, int requestCode)方法打开新的Activity,我们需要为startActivityForResult()方法传入一个请求码(第二个参数)。请求码的值是根据业务需要由自已设定,用于标识请求来源。

举例来说:比如一个Activity有两个按钮A和B,点击这两个按钮都会打开同一个Activity,不管是A按钮还是B按钮打开新Activity,当这个新Activity关闭后,系统都会调用前面Activity的onActivityResult(int requestCode, int resultCode, Intent data)方法。在onActivityResult()方法我们需要知道回传的数据由A按钮还是B按钮打开的,并且要做出相应的业务处理,这时就可以这样做:

@Override  
public void onCreate(Bundle savedInstanceState) {
        ....
        btn_a.setOnClickListener(new View.OnClickListener(){
            public void onClick(View v) {
                 Intent firstIntent = new Intent(FirstActivity.this, SecondActivity.class);
                // 请求码为1
                startActivityForResult (firstIntent, 1);

           }

        });
        btn_b.setOnClickListener(new View.OnClickListener(){
            public void onClick(View v) {
                 Intent secondIntent = new Intent(FirstActivity.this, SecondActivity.class);
                 // 请求码为2
                 startActivityForResult (secondIntent, 2);

            }

        });


       @Override 
       protected void onActivityResult(int requestCode, int resultCode, Intent data) {
               // 以请求码为判断依据
               switch(requestCode){
                   case 1:
                       //来自按钮A的请求,作相应业务处理
                       breakcase 2:
                       //来自按钮B的请求,作相应业务处理
                       break;
                }
          }
}

细细想一下,其实这个工作中是很有用的。
讲完了请求码,再讲讲结果码。

resultCode 结果码

在一个Activity中,可能会使用startActivityForResult()方法打开多个不同的Activity处理不同的业务,当这些新Activity关闭后,系统都会调用前面Activity的onActivityResult(int requestCode, int resultCode, Intent data)方法。为了知道返回的数据来自于哪个新Activity,在onActivityResult()方法中可以这样做(SecondActivity和ThreeActivity为要打开的新Activity):

public class SecondActivity extends Activity {
       .....
       SecondActivity.this.setResult(1, intent);
       SecondActivity.this.finish();
}
public class ThreeActivity extends Activity {
       ......
       ThreeActivity.this.setResult(2, intent);
       ThreeActivity.this.finish();
}
public class FirstActivity extends Activity { // 在该Activity会打开SecondActivity和ThreeActivity
       @Override 
       protected void onActivityResult(int requestCode, int resultCode, Intent data) {
               // 以结果码为判断依据
               switch(resultCode){
                   case 1:
                       // SecondActivity的返回数据
                       break;
                   case 2:
                       // ThreeActivity的返回数据
                       break;
                }
          }
} 
作者:programming_path 发表于2016/9/16 20:32:46 原文链接
阅读:81 评论:0 查看评论

android的Drawable详解

$
0
0

Drawable简介

Drawable有很多种,用来表示一种图像的概念,但他们又不完全是图像,他们是用过颜色构建出来的各种图像的表现形式。Drawable一般都是通过xml来定义的 ,当然我们也可以通过代码来创建,Drawable是一个抽象的类,是所以Drawable的基类,每个具体的Drawable都是它的子类,如ShapeDrawable,BitmapDrwable等,其结构如下图:


Drawable的内部有两个重要的参数需要说明,getIntrinsicHeight 和 getIntrinsicWidth,通过他们可以获取内部图片的高度和宽度,但是并不是所以的Drawable都有内部宽和高,比如一个颜色形成的Drawable就没有内部宽和高。

Drawable分类

Drawable种类繁多,比如,BitmapDrawable,ShapeDrwable,LayerDrawable,StateListDrawable等,这里就不一一列举了,下面列出一些常用的做一下简单的介绍。

ColorDrawable

colorDrawable是最简单的Drawable,它实际上是代表了单色可绘制区域,它包装了一种固定的颜色,当ColorDrawable被绘制到画布的时候会使用颜色填充Paint,在画布上绘制一块单色的区域。

在xml文件中使用color作为根节点来创建ColorDrawable,它只有一个android:color属性,通过它来决定ColorDrawable的颜色.

<?xml version="1.0" encoding="utf-8"?>
<color xmlns:android="http://schemas.android.com/apk/res/android"
 android:color="#FF0000" />

当然,我们也可以通过代码来创建,不过需要注意的是习惯使用十六进制格式的数据表示颜色值。

ColorDrawable drawable = new ColorDrawable(0xffff0000);

GradientDrawable

gradientDrawable表示一个渐变区域,可以实现线性渐变、发散渐变和平铺渐变效果,在Android中可以使用GradientDrawable表示很多复杂而又绚丽的界面效果。在xml文件中使用shape作为根节点来创建GradientDrawable,它包含很多属性和子节点,下面是GradientDrawable的xml文档节点结构。

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <size /> //定义区域的大小
    <gradient>//设置区域背景的渐变效果
        <solid/>//设置区域的背景颜色,如果设置了solid会覆盖gradient的效果
        <stroke />//设置区域的边框效果
        <padding />//设置区域的内边距
</shape>

BitmapDrawable

bitmapDrawable是对bitmap的一种包装,它表示的就是一张图片,我们可以通过xml方式来描述它。我们可以使用不同的属性含义来绘制他,如Android:src,android.dither等。

<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/png_icon_416"
    android:tileMode="mirror"
    android:antialias="true"
    android:dither="true"
    >
</bitmap>

当然我们用代码也是可以实现的。

Bitmap mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.png_icon_416);
BitmapDrawable mBitmapDrawable = new BitmapDrawable(mBitmap);
mBitmapDrawable.setTileModeXY(TileMode.MIRROR, TileMode.MIRROR);
mBitmapDrawable.setAntiAlias(true);
mBitmapDrawable.setDither(true);
mDrawable = mBitmapDrawable;

NinePatchDrawable

ninePatchDrawable用来表示一张.9格式的图片,为了实现缩放不失真的效果。Android SDK工具集提供了处理点九图片的工具,可以通过draw9patch.bat运行,通过这个工具可以很容易把普通的PNG图片处理成“点九”图片。从它的名字也很容易理解“点九”图的含义,其实相当于把一张PNG图分成了9个部分(九宫格),分别为4个角,4条边,以及一个中间区域,4个角是不做拉伸的,所以还能一直保持圆角的清晰状态,而2条水平边和2条垂直边分别只做水平和垂直拉伸,所以不会出现边框被拉粗的情况,只有中间用黑线指定的区域做拉伸,通过这种处理方式图片才不会失真。如图6-5所示,对4条黑线分别做了注释。左边和上边的黑线形成的矩形区域是图片的拉伸区域,下边和右边形成的矩形区域是内容所在的区域。黑线可以是连续的也可以是不连续的,不过为了达到最好的显示效果,最好使用连续的黑线。

使用了*.9.png图片技术后,只需要采用一套界面切图去适配不同的分辨率,而且大幅减少安装包的大小。


对于创建ninePatchDrawable也是极其简单的。

<?xml version="1.0" encoding="utf-8"?>
<nine-patch
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/droid_logo"
    android:dither="true" />
Android虽然可以使用Java代码创建NinePatchDrawable,但是极少情况会那么做,主要的原因是由于Android SDK会在编译工程时对点九图片进行编译,形成特殊格式的图片。使用代码创建NinePatchDrawable时只能针对编译过的点九图片资源,对于没有编译过的点九图片资源都当做BitmapDrawable对待。在使用点九图片时需要注意的是,点九图只能适用于拉伸的情况,对于压缩的情况并不适用,如果需要适配很多分辨率的屏幕时需要把点九图做的小一点。


ClipDrawable 

clipDrawable听名字就是对Drawable进行裁剪的。android中的进度条就是使用一个ClipDrawable实现效果的,它根据level的属性值,决定剪切区域的大小。

需要注意的是ClipDrawable是根据level的大小控制图片剪切操作的,level大小从0到10000。

<?xml version="1.0" encoding="utf-8"?>
<clip xmlns:android="http://schemas.android.com/apk/res/android"
    android:clipOrientation="horizontal"
    android:drawable="@drawable/bitmap_android"
    android:gravity="left"
    >
</clip>
需要注意的是如果没有android:drawable属性,必须要设置一个任意类型的drawable作为子节点。

<?xml version="1.0" encoding="utf-8"?>
<clip xmlns:android="http://schemas.android.com/apk/res/android"
    android:clipOrientation="horizontal"
    android:gravity="left"
    >
    <bitmap
        android:src="@drawable/android_text"
        android:gravity="center"
        />
</clip>

AnimationDrawable
animationDrawable就是动画的,这个是按帧播放的那种。使用起来也非常简单,在xml文件中使用animation-list作为根节点定义AnimationDrawable,使用item设置需要播放的每一帧使用的drawable资源,以及每一帧持续的时间即可。

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false">
    <item
        android:drawable="@drawable/level1"
        android:duration="300"
        />
    <item
        android:drawable="@drawable/level2"
        android:duration="300"
        />
    <item
        android:drawable="@drawable/level3"
        android:duration="300"
        />
    <item
        android:drawable="@drawable/level4"
        android:duration="300"
        />
    <item
        android:drawable="@drawable/level5"
        android:duration="300"
        />
</animation-list>
 代码实现,定义了AnimationDrawable之后需要主动调用AnimationDrawable的start播放动画,需要注意的是,当我们在Activity的oncreate方法中调用start方法时会没有任何效果,那是因为view还没有完成初始化,所以正确的使用方法是。

mHandler.postDelayed(new Runnable() {         
        @Override
        public void run() {
                // TODO Auto-generated method stub
                ((AnimationDrawable)mDrawable).start();               
        }
}, 1000);


LayerDrawable
layerDrawable顾名思义就是处于不同的层的,管理一组drawable,每个drawable都处于不同的层,当它们被绘制的时候,按照顺序全部都绘制到画布上。虽然有时候可能出现交错的情况,但是由于位于不同的层,显示上 也是不会有任何影响的。

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:drawable="@drawable/layer1" />
    <item android:drawable="@drawable/layer2" />
    <item android:drawable="@drawable/layer3" />
</layer-list>

LevelListDrawable

levelDrawable的每一个drawable都对应一个level范围,当它们被绘制的时候,根据level属性值选取对应的一个drawable绘制到画布上。就像波浪线一样。

<?xml version="1.0" encoding="utf-8"?>
<level-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item
        android:maxLevel="2000"
        android:drawable="@drawable/level1" />   
    <item
        android:maxLevel="4000"
        android:drawable="@drawable/level2" />
    <item
        android:maxLevel="6000"
        android:drawable="@drawable/level3" />
</level-list>


StateListDrawable
stateListDrawable管理一组drawable,每一个drawable都对应着一组状态,状态的选择类似于java中的switch-case组合,按照顺序比较状态,当遇到匹配的状态后,就返回对应的drawable,因此需要把最精确的匹配放置在最前面,按照从精确到粗略的顺序排列。这也是我们开发中用的最多的,写背景选择器的时候,我们一般只会使用两种状态,其实它可以表示很多种状态,几乎可以实现很多效果。

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:state_focused="false"
        android:state_pressed="false"
        android:drawable="@drawable/gradient_normal"
        />    
    <item android:state_pressed="true"
        android:drawable="@drawable/gradient_pressed"
        />
    <item android:state_focused="true"
        android:drawable="@drawable/gradient_focused"
        />
</selector>

其实还有些Drawable,这里就不一一讲解了。




作者:xiangzhihong8 发表于2016/9/16 21:17:44 原文链接
阅读:108 评论:0 查看评论

利用C语言图像界面绘制操作系统1

$
0
0

有了C语言这一利器后,不多多拿来用,那就太对不起前面的一系列努力了。那么怎么表现C语言的强大功能呢,如果还只是一味的在界面上输出几行字符,那太没意思,考虑到,我们的目标是做出像windows那样具备舒心的图像用户界面那样的系统,所以在这一节,我们由字符模式切换入画面模式,初步体验下,那些绚丽多彩的图像界面是如何发展而成的。

要想由字符模式转入图形模式,我们需要操作硬件,特别是向显卡发送命令,让其进入图形显示模式,就如同前面我们所做的,要操作硬件,一般需要使用BIOS调用,以下几行就是打开VGA显卡色彩功能的代码:

mov al, 0x13h
mov ah, 0x00
int 0x10
1
2
3
其中al 的值决定了要设置显卡的色彩模式,下面是一些常用的模式设置:
1. 0x03, 16色字符模式
2. 0x12, VGA图形模式, 640 * 480 * 4位彩色模式,独特的4面存储模式
3. 0x13, VGA图形模式, 320 * 200 * 8位彩色模式,调色板模式
4. 0x6a, 扩展VGA图形模式, 800 * 600 * 4彩色模式

我们采用的是0x13模式,其中320*200*8 中,最后的数值8表示的是色彩值得位数,也就是我们可以用8位数值表示色彩,总共可以显示256种色彩。

系统显存的地址是0x000a0000,当我们执行上面几句代码后,望显存地址写入数据,那么屏幕就会出现相应的变化了。

我们先看看内核的汇编代码部分(kernel.asm):

%include “pm.inc”

org 0x9000

jmp LABEL_BEGIN

[SECTION .gdt]
; 段基址 段界限 属性
LABEL_GDT: Descriptor 0, 0, 0
LABEL_DESC_CODE32: Descriptor 0, SegCode32Len - 1, DA_C + DA_32
LABEL_DESC_VIDEO: Descriptor 0B8000h, 0ffffh, DA_DRW
LABEL_DESC_VRAM: Descriptor 0, 0ffffffffh, DA_DRW
LABEL_DESC_STACK: Descriptor 0, TopOfStack, DA_DRWA+DA_32

GdtLen equ $ - LABEL_GDT
GdtPtr dw GdtLen - 1
dd 0

SelectorCode32 equ LABEL_DESC_CODE32 - LABEL_GDT
SelectorVideo equ LABEL_DESC_VIDEO - LABEL_GDT
SelectorStack equ LABEL_DESC_STACK - LABEL_GDT
SelectorVram equ LABEL_DESC_VRAM - LABEL_GDT

[SECTION .s16]
[BITS 16]
LABEL_BEGIN:
mov ax, cs
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0100h

 mov   al, 0x13
 mov   ah, 0
 int   0x10

 xor   eax, eax
 mov   ax,  cs
 shl   eax, 4
 add   eax, LABEL_SEG_CODE32
 mov   word [LABEL_DESC_CODE32 + 2], ax
 shr   eax, 16
 mov   byte [LABEL_DESC_CODE32 + 4], al
 mov   byte [LABEL_DESC_CODE32 + 7], ah

 ;set stack for C language
 xor   eax, eax
 mov   ax,  cs
 shl   eax, 4
 add   eax, LABEL_STACK
 mov   word [LABEL_DESC_STACK + 2], ax
 shr   eax, 16
 mov   byte [LABEL_DESC_STACK + 4], al
 mov   byte [LABEL_DESC_STACK + 7], ah

 xor   eax, eax
 mov   ax, ds
 shl   eax, 4
 add   eax,  LABEL_GDT
 mov   dword  [GdtPtr + 2], eax

 lgdt  [GdtPtr]

 cli   ;关中断

 in    al,  92h
 or    al,  00000010b
 out   92h, al

 mov   eax, cr0
 or    eax , 1
 mov   cr0, eax

 jmp   dword  SelectorCode32: 0

 [SECTION .s32]
 [BITS  32]
 LABEL_SEG_CODE32:
 ;initialize stack for c code
 mov  ax, SelectorStack
 mov  ss, ax
 mov  esp, TopOfStack

 mov  ax, SelectorVram
 mov  ds,  ax

C_CODE_ENTRY:
%include “write_vga.asm”

 io_hlt:  ;void io_hlt(void);
  HLT
  RET

SegCode32Len equ $ - LABEL_SEG_CODE32

[SECTION .gs]
ALIGN 32
[BITS 32]
LABEL_STACK:
times 512 db 0
TopOfStack equ $ - LABEL_STACK
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
解释下上面代码,我们设置了一个描述符,LABEL_DESC_VRAM, 这个描述符对应的内存起始地址是0,长度是0xffffffff,也就是我们把整个4G内存当做一段可读可写的内存,有了这个设置后,我们在C语言里就可以随意读写内存的任何地方。

LABEL_DESC_STACK 这个描述符用来设置一段可读可写的内存,它的起始地址是LABEL_STACK, 可以看到,程序通过语句:times 512 db 0
初始化了512字节的内存。C语言的运行,特别是函数调用时,是需要一个堆栈来传递参数的,所以,要运行C语言,我们首先需要为其配置一个堆栈,该描述符所对应的这512自己内存就是给C语言使用的,由于堆栈只有512字节,在后面我们使用C语言写的代码中,函数的局部变量大小不能超过512字节,例如下面的代码可能就要出错了:

void fun() {
char buf[513];
}
1
2
3
语句%include write_vga.asm”, 表明,我们要开发的C代码文件叫write_vga.c, 我们写完C代码后,会使用上一节的步骤将它编译成汇编,然后include到我们当前的汇编文件里,统一编译成可执行内核。

最后一小块代码:
io_hlt: ;void io_hlt(void);
HLT
RET
作用是进入死循环,HLT指令会让系统进入休眠状态。

导入C语言

硬件,堆栈等基层设施通过汇编准备就绪后,我们可以使用C语言开发图形功能了。显示器的每一个像素对应一个点,一个点可以显示256种不同的颜色,因此,只要我们给每个点设置成相应的颜色,那么最终就可以绘制出特定的图像。

我们看看如何用C语言写入显存从而操作屏幕图像,write_ram.c:

void CMain(void) {
int i;
char*p = 0;

for (i = 0xa0000; i <= 0xaffff; i++) {
    p = i;
    *p = i & 0x0f;  
}

for(;;) {
   io_hlt();
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
代码中,我们将指针P指向地址0xa0000, 这个地址正好就是vga显存地址,vga显存地址从0xa0000开始,直到0xaffff结束,总共64k.接着语句:
*p = i & 0x0f 将一个数值写入显存,这个值可以是0-256中任意一个数值,我们代码里是将i的最后4位作为像素颜色写入显存,这个值是任意的,大家可以随意设置。

在Ubuntu中写出上面代码后,通过命令编译成二进制文件:
gcc -m32 -fno-asynchronous-unwind-tables -s -c -o write_vga.asm write_vga.c

于是在目录下会生成write_vga.o二进制文件,接着使用objconv进行反汇编:
./objconv -fnasm write_vga.asm write_vga.o
反汇编后代码如下:

; Disassembly of file: write_vga.o
; Tue Sep 13 10:30:14 2016
; Mode: 32 bits
; Syntax: YASM/NASM
; Instruction set: 80386

global CMain: function

extern io_hlt ; near

SECTION .text align=1 execute ; section number 1, code

CMain: ; Function begin
push ebp ; 0000 _ 55
mov ebp, esp ; 0001 _ 89. E5
sub esp, 24 ; 0003 _ 83. EC, 18
mov dword [ebp-0CH], 0 ; 0006 _ C7. 45, F4, 00000000
mov dword [ebp-10H], 655360 ; 000D _ C7. 45, F0, 000A0000
jmp ?002 ; 0014 EB, 17

?001: mov eax, dword [ebp-10H] ; 0016 8B. 45, F0
mov dword [ebp-0CH], eax ; 0019 _ 89. 45, F4
mov eax, dword [ebp-10H] ; 001C _ 8B. 45, F0
and eax, 0FH ; 001F _ 83. E0, 0F
mov edx, eax ; 0022 _ 89. C2
mov eax, dword [ebp-0CH] ; 0024 _ 8B. 45, F4
mov byte [eax], dl ; 0027 _ 88. 10
add dword [ebp-10H], 1 ; 0029 _ 83. 45, F0, 01
?002: cmp dword [ebp-10H], 720895 ; 002D 81. 7D, F0, 000AFFFF
jle ?001 ; 0034 7E, E0
?003: call io_hlt ; 0036 E8, FFFFFFFC(rel)
jmp ?003 ; 003B EB, F9
; CMain End of function

SECTION .data align=1 noexecute ; section number 2, data

SECTION .bss align=1 noexecute ; section number 3, bss
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
在上面代码中去掉以section 开始的指令,这些指令会影响我们把当前汇编结合入内核kerne.asm.
同时去掉开头的两句:

global CMain: function
extern io_hlt

因为我们要把两个汇编文件结合成一个,所以这两句声明是多余的。做完这些后,再用nasm编译kernel.asm:
nasm -o kernel.bat kernel.asm
于是本地目录下,内核文件就编译好了。

接着运行java工程,生成虚拟软盘,运行结果如下:
这里写图片描述

大家注意看,kernel.bat写入了两个扇区,也就是说,我们内核的大小已经超过了512字节。此时我们需要修改一下内核加载器,让内核加载器一次读入两个扇区才能把内核完全加载入内存,打开boot.asm,将readFloppy中的:
mov ah, 0x02
mov al, 1
http://www.yqcq.gov.cn/e/space/?userid=651393&yqcq.xml?feed_filter=20160916Lz3Vv.html
http://www.yqcq.gov.cn/e/space/?userid=651394&yqcq.xml?feed_filter=20160916Ho0Fs.html
http://www.yqcq.gov.cn/e/space/?userid=651397&yqcq.xml?feed_filter=20160916Qj7Sm.html
http://www.yqcq.gov.cn/e/space/?userid=651400&yqcq.xml?feed_filter=20160916Xs1Rj.html
http://www.yqcq.gov.cn/e/space/?userid=651403&yqcq.xml?feed_filter=20160916Jb1Qr.html
http://www.yqcq.gov.cn/e/space/?userid=651406&yqcq.xml?feed_filter=20160916Ox8Ma.html
http://www.yqcq.gov.cn/e/space/?userid=651407&yqcq.xml?feed_filter=20160916Es7Hk.html
http://www.yqcq.gov.cn/e/space/?userid=651409&yqcq.xml?feed_filter=20160916Gg0Ao.html
http://www.yqcq.gov.cn/e/space/?userid=651410&yqcq.xml?feed_filter=20160916Ns1Am.html
http://www.yqcq.gov.cn/e/space/?userid=651412&yqcq.xml?feed_filter=20160916Lu7Jx.html
http://www.yqcq.gov.cn/e/space/?userid=651415&yqcq.xml?feed_filter=20160916Do5Av.html
http://www.yqcq.gov.cn/e/space/?userid=651416&yqcq.xml?feed_filter=20160916Qa1Gt.html
http://www.yqcq.gov.cn/e/space/?userid=651418&yqcq.xml?feed_filter=20160916Ks6Jj.html
http://www.yqcq.gov.cn/e/space/?userid=651421&yqcq.xml?feed_filter=20160916Me7Fv.html
http://www.yqcq.gov.cn/e/space/?userid=651423&yqcq.xml?feed_filter=20160916Wt5Uv.html
http://www.yqcq.gov.cn/e/space/?userid=651425&yqcq.xml?feed_filter=20160916Cb9Ab.html
http://www.yqcq.gov.cn/e/space/?userid=651427&yqcq.xml?feed_filter=20160916Kg3Hc.html
http://www.yqcq.gov.cn/e/space/?userid=651429&yqcq.xml?feed_filter=20160916Wj1Li.html
http://www.yqcq.gov.cn/e/space/?userid=651431&yqcq.xml?feed_filter=20160916Ux4Gc.html
http://www.yqcq.gov.cn/e/space/?userid=651433&yqcq.xml?feed_filter=20160916Sm3We.html
http://www.yqcq.gov.cn/e/space/?userid=651434&yqcq.xml?feed_filter=20160916Cj8Fv.html
http://www.yqcq.gov.cn/e/space/?userid=651437&yqcq.xml?feed_filter=20160916Kb8Jp.html
http://www.yqcq.gov.cn/e/space/?userid=651439&yqcq.xml?feed_filter=20160916Fc6Os.html
http://www.yqcq.gov.cn/e/space/?userid=651441&yqcq.xml?feed_filter=20160916Gz8Og.html
http://www.yqcq.gov.cn/e/space/?userid=651442&yqcq.xml?feed_filter=20160916Ly1Bb.html
http://www.yqcq.gov.cn/e/space/?userid=651444&yqcq.xml?feed_filter=20160916Na4Dd.html
http://www.yqcq.gov.cn/e/space/?userid=651445&yqcq.xml?feed_filter=20160916Fa0Tk.html
http://www.yqcq.gov.cn/e/space/?userid=651447&yqcq.xml?feed_filter=20160916Vs3Ys.html
http://www.yqcq.gov.cn/e/space/?userid=651450&yqcq.xml?feed_filter=20160916Ji2Qf.html
http://www.yqcq.gov.cn/e/space/?userid=651451&yqcq.xml?feed_filter=20160916Wk4Sk.html
http://www.yqcq.gov.cn/e/space/?userid=651453&yqcq.xml?feed_filter=20160916Du7Hf.html
http://www.yqcq.gov.cn/e/space/?userid=651455&yqcq.xml?feed_filter=20160916Uk5Dy.html
http://www.yqcq.gov.cn/e/space/?userid=651456&yqcq.xml?feed_filter=20160916Om5Dl.html
http://www.yqcq.gov.cn/e/space/?userid=651459&yqcq.xml?feed_filter=20160916Mb0Fq.html
http://www.yqcq.gov.cn/e/space/?userid=651460&yqcq.xml?feed_filter=20160916Cb9Gd.html
http://www.yqcq.gov.cn/e/space/?userid=651464&yqcq.xml?feed_filter=20160916Qe1Ys.html
http://www.yqcq.gov.cn/e/space/?userid=651465&yqcq.xml?feed_filter=20160916Pj2An.html
http://www.yqcq.gov.cn/e/space/?userid=651469&yqcq.xml?feed_filter=20160916Yw0Yq.html
http://www.yqcq.gov.cn/e/space/?userid=651471&yqcq.xml?feed_filter=20160916Ax6Lr.html
http://www.yqcq.gov.cn/e/space/?userid=651473&yqcq.xml?feed_filter=20160916Zs5De.html
http://www.yqcq.gov.cn/e/space/?userid=651475&yqcq.xml?feed_filter=20160916Cx9Fq.html
http://www.yqcq.gov.cn/e/space/?userid=651477&yqcq.xml?feed_filter=20160916Ip0Bz.html
http://www.yqcq.gov.cn/e/space/?userid=651478&yqcq.xml?feed_filter=20160916Ji0Pb.html
http://www.yqcq.gov.cn/e/space/?userid=651480&yqcq.xml?feed_filter=20160916Je1Hq.html
http://www.yqcq.gov.cn/e/space/?userid=651482&yqcq.xml?feed_filter=20160916Jv9De.html
http://www.yqcq.gov.cn/e/space/?userid=651483&yqcq.xml?feed_filter=20160916Ov8Fb.html
http://www.yqcq.gov.cn/e/space/?userid=651485&yqcq.xml?feed_filter=20160916Ul2Ud.html
http://www.yqcq.gov.cn/e/space/?userid=651487&yqcq.xml?feed_filter=20160916Up8Ti.html
http://www.yqcq.gov.cn/e/space/?userid=651488&yqcq.xml?feed_filter=20160916Kz5Ss.html
http://www.yqcq.gov.cn/e/space/?userid=651490&yqcq.xml?feed_filter=20160916Bq6Nn.html
http://www.yqcq.gov.cn/e/space/?userid=651492&yqcq.xml?feed_filter=20160916Kw9Ux.html
http://www.yqcq.gov.cn/e/space/?userid=651494&yqcq.xml?feed_filter=20160916Tm1Jx.html
http://www.yqcq.gov.cn/e/space/?userid=651496&yqcq.xml?feed_filter=20160916Bb9Sh.html
http://www.yqcq.gov.cn/e/space/?userid=651498&yqcq.xml?feed_filter=20160916Kr3Pb.html
http://www.yqcq.gov.cn/e/space/?userid=651499&yqcq.xml?feed_filter=20160916Dm7St.html
http://www.yqcq.gov.cn/e/space/?userid=651501&yqcq.xml?feed_filter=20160916Xv0Pv.html
http://www.yqcq.gov.cn/e/space/?userid=651502&yqcq.xml?feed_filter=20160916Ka8Lt.html
http://www.yqcq.gov.cn/e/space/?userid=651505&yqcq.xml?feed_filter=20160916Zh7Xz.html
http://www.yqcq.gov.cn/e/space/?userid=651507&yqcq.xml?feed_filter=20160916Lm5Zj.html
http://www.yqcq.gov.cn/e/space/?userid=651510&yqcq.xml?feed_filter=20160916Kc7Pn.html
http://www.yqcq.gov.cn/e/space/?userid=651512&yqcq.xml?feed_filter=20160916Qf0Xe.html
http://www.yqcq.gov.cn/e/space/?userid=651514&yqcq.xml?feed_filter=20160916Ct0Ma.html
http://www.yqcq.gov.cn/e/space/?userid=651516&yqcq.xml?feed_filter=20160916Rs4Aw.html
http://www.yqcq.gov.cn/e/space/?userid=651518&yqcq.xml?feed_filter=20160916Zs5Mu.html
http://www.yqcq.gov.cn/e/space/?userid=651520&yqcq.xml?feed_filter=20160916Dm1Cv.html
http://www.yqcq.gov.cn/e/space/?userid=651522&yqcq.xml?feed_filter=20160916Ce1Tv.html
http://www.yqcq.gov.cn/e/space/?userid=651523&yqcq.xml?feed_filter=20160916Gc4Fw.html
http://www.yqcq.gov.cn/e/space/?userid=651526&yqcq.xml?feed_filter=20160916Iu6Ly.html
http://www.yqcq.gov.cn/e/space/?userid=651529&yqcq.xml?feed_filter=20160916Cg6Lr.html
http://www.yqcq.gov.cn/e/space/?userid=651530&yqcq.xml?feed_filter=20160916Pv9Is.html
http://www.yqcq.gov.cn/e/space/?userid=651533&yqcq.xml?feed_filter=20160916Cn5Kn.html
http://www.yqcq.gov.cn/e/space/?userid=651535&yqcq.xml?feed_filter=20160916Pi5Ev.html
http://www.yqcq.gov.cn/e/space/?userid=651537&yqcq.xml?feed_filter=20160916Nr6Mq.html
http://www.yqcq.gov.cn/e/space/?userid=651539&yqcq.xml?feed_filter=20160916Sk4Jj.html
http://www.yqcq.gov.cn/e/space/?userid=651541&yqcq.xml?feed_filter=20160916Kw0Pm.html
http://www.yqcq.gov.cn/e/space/?userid=651544&yqcq.xml?feed_filter=20160916Nw9Qd.html
http://www.yqcq.gov.cn/e/space/?userid=651545&yqcq.xml?feed_filter=20160916Af7Sc.html
http://www.yqcq.gov.cn/e/space/?userid=651548&yqcq.xml?feed_filter=20160916Ig7Fn.html
http://www.yqcq.gov.cn/e/space/?userid=651551&yqcq.xml?feed_filter=20160916Sz1Ze.html
http://www.yqcq.gov.cn/e/space/?userid=651553&yqcq.xml?feed_filter=20160916Vt4Mt.html
http://www.yqcq.gov.cn/e/space/?userid=651555&yqcq.xml?feed_filter=20160916Zs9Ay.html
http://www.yqcq.gov.cn/e/space/?userid=651556&yqcq.xml?feed_filter=20160916Vs2Gl.html
http://www.yqcq.gov.cn/e/space/?userid=651560&yqcq.xml?feed_filter=20160916Wc4Fx.html
http://www.yqcq.gov.cn/e/space/?userid=651563&yqcq.xml?feed_filter=20160916Qu8Fq.html
http://www.yqcq.gov.cn/e/space/?userid=651564&yqcq.xml?feed_filter=20160916Ew7Mx.html
http://www.yqcq.gov.cn/e/space/?userid=651567&yqcq.xml?feed_filter=20160916Vk7Fv.html
http://www.yqcq.gov.cn/e/space/?userid=651570&yqcq.xml?feed_filter=20160916Dc5Vw.html
http://www.yqcq.gov.cn/e/space/?userid=651572&yqcq.xml?feed_filter=20160916Yz0Sr.html
http://www.yqcq.gov.cn/e/space/?userid=651575&yqcq.xml?feed_filter=20160916Bx6Kv.html
http://www.yqcq.gov.cn/e/space/?userid=651578&yqcq.xml?feed_filter=20160916Tk6Dr.html
http://www.yqcq.gov.cn/e/space/?userid=651581&yqcq.xml?feed_filter=20160916An2Dp.html
http://www.yqcq.gov.cn/e/space/?userid=651583&yqcq.xml?feed_filter=20160916Pw5Su.html
http://www.yqcq.gov.cn/e/space/?userid=651586&yqcq.xml?feed_filter=20160916Do6Fc.html
http://www.yqcq.gov.cn/e/space/?userid=651588&yqcq.xml?feed_filter=20160916Eq1Ct.html
http://www.yqcq.gov.cn/e/space/?userid=651590&yqcq.xml?feed_filter=20160916Bx7Si.html
http://www.yqcq.gov.cn/e/space/?userid=651592&yqcq.xml?feed_filter=20160916Xc9Rx.html
http://www.yqcq.gov.cn/e/space/?userid=651594&yqcq.xml?feed_filter=20160916Ur3Tz.html
http://www.yqcq.gov.cn/e/space/?userid=651596&yqcq.xml?feed_filter=20160916Ux0Cx.html
http://www.yqcq.gov.cn/e/space/?userid=651598&yqcq.xml?feed_filter=20160916Uo1Nz.html
http://www.yqcq.gov.cn/e/space/?userid=651601&yqcq.xml?feed_filter=20160916Tw2Mz.html
http://www.yqcq.gov.cn/e/space/?userid=651602&yqcq.xml?feed_filter=20160916Xi0Ov.html
http://www.yqcq.gov.cn/e/space/?userid=651605&yqcq.xml?feed_filter=20160916Xk4Yh.html
http://www.yqcq.gov.cn/e/space/?userid=651607&yqcq.xml?feed_filter=20160916Cw4Kq.html
http://www.yqcq.gov.cn/e/space/?userid=651609&yqcq.xml?feed_filter=20160916Cm9Dw.html
http://www.yqcq.gov.cn/e/space/?userid=651612&yqcq.xml?feed_filter=20160916Nk0Oe.html
http://www.yqcq.gov.cn/e/space/?userid=651614&yqcq.xml?feed_filter=20160916Yp9Hm.html
http://www.yqcq.gov.cn/e/space/?userid=651616&yqcq.xml?feed_filter=20160916Wn7Kj.html
http://www.yqcq.gov.cn/e/space/?userid=651618&yqcq.xml?feed_filter=20160916Uu9Ph.html
http://www.yqcq.gov.cn/e/space/?userid=651620&yqcq.xml?feed_filter=20160916Mg7Tc.html
http://www.yqcq.gov.cn/e/space/?userid=651622&yqcq.xml?feed_filter=20160916Tb1No.html
http://www.yqcq.gov.cn/e/space/?userid=651623&yqcq.xml?feed_filter=20160916Yq1Hf.html
http://www.yqcq.gov.cn/e/space/?userid=651625&yqcq.xml?feed_filter=20160916Lv6Ei.html
http://www.yqcq.gov.cn/e/space/?userid=651626&yqcq.xml?feed_filter=20160916Mu3Dm.html
http://www.yqcq.gov.cn/e/space/?userid=651628&yqcq.xml?feed_filter=20160916Mf5Al.html
http://www.yqcq.gov.cn/e/space/?userid=651630&yqcq.xml?feed_filter=20160916Ww8Ve.html
http://www.yqcq.gov.cn/e/space/?userid=651631&yqcq.xml?feed_filter=20160916Qs2Mu.html
http://www.yqcq.gov.cn/e/space/?userid=651633&yqcq.xml?feed_filter=20160916Lb1Lq.html
http://www.yqcq.gov.cn/e/space/?userid=651634&yqcq.xml?feed_filter=20160916Bh2Wg.html
http://www.yqcq.gov.cn/e/space/?userid=651637&yqcq.xml?feed_filter=20160916Xp8Vl.html
http://www.yqcq.gov.cn/e/space/?userid=651639&yqcq.xml?feed_filter=20160916Iv8Ps.html
http://www.yqcq.gov.cn/e/space/?userid=651640&yqcq.xml?feed_filter=20160916Kf8Ho.html
http://www.yqcq.gov.cn/e/space/?userid=651641&yqcq.xml?feed_filter=20160916Mb2Vg.html
http://www.yqcq.gov.cn/e/space/?userid=651643&yqcq.xml?feed_filter=20160916Ef9Qe.html
http://www.yqcq.gov.cn/e/space/?userid=651645&yqcq.xml?feed_filter=20160916Zi6Hv.html
http://www.yqcq.gov.cn/e/space/?userid=651646&yqcq.xml?feed_filter=20160916Wa2Cy.html
http://www.yqcq.gov.cn/e/space/?userid=651648&yqcq.xml?feed_filter=20160916Bd4Dv.html
http://www.yqcq.gov.cn/e/space/?userid=651649&yqcq.xml?feed_filter=20160916Pd8Kz.html
http://www.yqcq.gov.cn/e/space/?userid=651651&yqcq.xml?feed_filter=20160916Ag2Sa.html
http://www.yqcq.gov.cn/e/space/?userid=651653&yqcq.xml?feed_filter=20160916Fb2Dg.html
http://www.yqcq.gov.cn/e/space/?userid=651655&yqcq.xml?feed_filter=20160916Fg6Ax.html
http://www.yqcq.gov.cn/e/space/?userid=651657&yqcq.xml?feed_filter=20160916Ar2Nl.html
http://www.yqcq.gov.cn/e/space/?userid=651658&yqcq.xml?feed_filter=20160916Wk4Bo.html
http://www.yqcq.gov.cn/e/space/?userid=651660&yqcq.xml?feed_filter=20160916Sr6Uy.html
http://www.yqcq.gov.cn/e/space/?userid=651663&yqcq.xml?feed_filter=20160916Vr2Th.html
http://www.yqcq.gov.cn/e/space/?userid=651665&yqcq.xml?feed_filter=20160916Si1Nj.html
http://www.yqcq.gov.cn/e/space/?userid=651667&yqcq.xml?feed_filter=20160916Mu4Az.html
http://www.yqcq.gov.cn/e/space/?userid=651669&yqcq.xml?feed_filter=20160916Ib2Jf.html
http://www.yqcq.gov.cn/e/space/?userid=651671&yqcq.xml?feed_filter=20160916Hn8Do.html
http://www.yqcq.gov.cn/e/space/?userid=651673&yqcq.xml?feed_filter=20160916Uz8Qs.html
http://www.yqcq.gov.cn/e/space/?userid=651675&yqcq.xml?feed_filter=20160916Dh6Wa.html
http://www.yqcq.gov.cn/e/space/?userid=651677&yqcq.xml?feed_filter=20160916Ph1He.html
http://www.yqcq.gov.cn/e/space/?userid=651679&yqcq.xml?feed_filter=20160916Py6Cc.html
http://www.yqcq.gov.cn/e/space/?userid=651680&yqcq.xml?feed_filter=20160916We4My.html
http://www.yqcq.gov.cn/e/space/?userid=651683&yqcq.xml?feed_filter=20160916Kd3Pc.html
http://www.yqcq.gov.cn/e/space/?userid=651686&yqcq.xml?feed_filter=20160916Px6Dx.html
http://www.yqcq.gov.cn/e/space/?userid=651688&yqcq.xml?feed_filter=20160916Cm2En.html
http://www.yqcq.gov.cn/e/space/?userid=651690&yqcq.xml?feed_filter=20160916Cd9Ar.html
http://www.yqcq.gov.cn/e/space/?userid=651693&yqcq.xml?feed_filter=20160916Fq6Dx.html
http://www.yqcq.gov.cn/e/space/?userid=651694&yqcq.xml?feed_filter=20160916Fp1Rg.html
http://www.yqcq.gov.cn/e/space/?userid=651698&yqcq.xml?feed_filter=20160916Si9Yy.html
http://www.yqcq.gov.cn/e/space/?userid=651701&yqcq.xml?feed_filter=20160916Bb3Cj.html
http://www.yqcq.gov.cn/e/space/?userid=651702&yqcq.xml?feed_filter=20160916Dj5Oz.html
http://www.yqcq.gov.cn/e/space/?userid=651705&yqcq.xml?feed_filter=20160916Tq2Da.html
http://www.yqcq.gov.cn/e/space/?userid=651707&yqcq.xml?feed_filter=20160916Og5Hy.html
http://www.yqcq.gov.cn/e/space/?userid=651709&yqcq.xml?feed_filter=20160916Qf9Kt.html
http://www.yqcq.gov.cn/e/space/?userid=651710&yqcq.xml?feed_filter=20160916Ax4Ir.html
http://www.yqcq.gov.cn/e/space/?userid=651713&yqcq.xml?feed_filter=20160916Vr6Zi.html
http://www.yqcq.gov.cn/e/space/?userid=651715&yqcq.xml?feed_filter=20160916Ff0Bp.html
http://www.yqcq.gov.cn/e/space/?userid=651717&yqcq.xml?feed_filter=20160916Ib7De.html
http://www.yqcq.gov.cn/e/space/?userid=651719&yqcq.xml?feed_filter=20160916Oe6Pt.html
http://www.yqcq.gov.cn/e/space/?userid=651721&yqcq.xml?feed_filter=20160916Dq4Mq.html
http://www.yqcq.gov.cn/e/space/?userid=651723&yqcq.xml?feed_filter=20160916Bf5Mv.html
http://www.yqcq.gov.cn/e/space/?userid=651726&yqcq.xml?feed_filter=20160916Qf5Yi.html
http://www.yqcq.gov.cn/e/space/?userid=651728&yqcq.xml?feed_filter=20160916Gc3Ez.html
http://www.yqcq.gov.cn/e/space/?userid=651730&yqcq.xml?feed_filter=20160916Dg4Bc.html
http://www.yqcq.gov.cn/e/space/?userid=651733&yqcq.xml?feed_filter=20160916Ig7Vt.html
http://www.yqcq.gov.cn/e/space/?userid=651735&yqcq.xml?feed_filter=20160916Xw9Za.html
http://www.yqcq.gov.cn/e/space/?userid=651739&yqcq.xml?feed_filter=20160916Ty6Vf.html
http://www.yqcq.gov.cn/e/space/?userid=651740&yqcq.xml?feed_filter=20160916Zh2Zv.html
http://www.yqcq.gov.cn/e/space/?userid=651743&yqcq.xml?feed_filter=20160916Vc8Pq.html
http://www.yqcq.gov.cn/e/space/?userid=651745&yqcq.xml?feed_filter=20160916Eo7Qe.html
http://www.yqcq.gov.cn/e/space/?userid=651747&yqcq.xml?feed_filter=20160916Fh6Lr.html
http://www.yqcq.gov.cn/e/space/?userid=651750&yqcq.xml?feed_filter=20160916Up9Yp.html
http://www.yqcq.gov.cn/e/space/?userid=651754&yqcq.xml?feed_filter=20160916Dx7Se.html
http://www.yqcq.gov.cn/e/space/?userid=651756&yqcq.xml?feed_filter=20160916Vv1Uq.html
http://www.yqcq.gov.cn/e/space/?userid=651758&yqcq.xml?feed_filter=20160916Jb9Ah.html
http://www.yqcq.gov.cn/e/space/?userid=651761&yqcq.xml?feed_filter=20160916Qr0Yr.html
http://www.yqcq.gov.cn/e/space/?userid=651763&yqcq.xml?feed_filter=20160916Yf2As.html
http://www.yqcq.gov.cn/e/space/?userid=651765&yqcq.xml?feed_filter=20160916Ez8As.html
http://www.yqcq.gov.cn/e/space/?userid=651767&yqcq.xml?feed_filter=20160916Xe1Ek.html
http://www.yqcq.gov.cn/e/space/?userid=651769&yqcq.xml?feed_filter=20160916Cg9Ka.html
http://www.yqcq.gov.cn/e/space/?userid=651772&yqcq.xml?feed_filter=20160916Ef5Cy.html
http://www.yqcq.gov.cn/e/space/?userid=651775&yqcq.xml?feed_filter=20160916Ak4Gu.html
http://www.yqcq.gov.cn/e/space/?userid=651777&yqcq.xml?feed_filter=20160916Hx1Gm.html
http://www.yqcq.gov.cn/e/space/?userid=651780&yqcq.xml?feed_filter=20160916Uv8Ow.html
http://www.yqcq.gov.cn/e/space/?userid=651781&yqcq.xml?feed_filter=20160916Qz4Nm.html
http://www.yqcq.gov.cn/e/space/?userid=651784&yqcq.xml?feed_filter=20160916Au8Dg.html
http://www.yqcq.gov.cn/e/space/?userid=651786&yqcq.xml?feed_filter=20160916Zv8Ng.html
http://www.yqcq.gov.cn/e/space/?userid=651789&yqcq.xml?feed_filter=20160916Il1Np.html
http://www.yqcq.gov.cn/e/space/?userid=651791&yqcq.xml?feed_filter=20160916Ee1Lt.html
http://www.yqcq.gov.cn/e/space/?userid=651792&yqcq.xml?feed_filter=20160916Wg3Df.html
http://www.yqcq.gov.cn/e/space/?userid=651794&yqcq.xml?feed_filter=20160916Pe4Qf.html
http://www.yqcq.gov.cn/e/space/?userid=651797&yqcq.xml?feed_filter=20160916Ct2Oe.html
http://www.yqcq.gov.cn/e/space/?userid=651799&yqcq.xml?feed_filter=20160916Hu2Ua.html
http://www.yqcq.gov.cn/e/space/?userid=651801&yqcq.xml?feed_filter=20160916Rl3Ap.html
http://www.yqcq.gov.cn/e/space/?userid=651804&yqcq.xml?feed_filter=20160916Bo9Nz.html
http://www.yqcq.gov.cn/e/space/?userid=651806&yqcq.xml?feed_filter=20160916Oi3Bo.html
http://www.yqcq.gov.cn/e/space/?userid=651808&yqcq.xml?feed_filter=20160916Mv8Dr.html
http://www.yqcq.gov.cn/e/space/?userid=651810&yqcq.xml?feed_filter=20160916Rl6Fg.html
http://www.yqcq.gov.cn/e/space/?userid=651813&yqcq.xml?feed_filter=20160916Yy0Ou.html
http://www.yqcq.gov.cn/e/space/?userid=651814&yqcq.xml?feed_filter=20160916Me8Qz.html
http://www.yqcq.gov.cn/e/space/?userid=651817&yqcq.xml?feed_filter=20160916Ej9Rs.html
http://www.yqcq.gov.cn/e/space/?userid=651819&yqcq.xml?feed_filter=20160916Ay0Vd.html
http://www.yqcq.gov.cn/e/space/?userid=651821&yqcq.xml?feed_filter=20160916Cn6Pg.html
http://www.yqcq.gov.cn/e/space/?userid=651823&yqcq.xml?feed_filter=20160916By2Cv.html
http://www.yqcq.gov.cn/e/space/?userid=651824&yqcq.xml?feed_filter=20160916Iy7Qm.html
http://www.yqcq.gov.cn/e/space/?userid=651826&yqcq.xml?feed_filter=20160916Br8Gb.html
http://www.yqcq.gov.cn/e/space/?userid=651827&yqcq.xml?feed_filter=20160916Fx9Li.html
http://www.yqcq.gov.cn/e/space/?userid=651829&yqcq.xml?feed_filter=20160916He6Hj.html
http://www.yqcq.gov.cn/e/space/?userid=651832&yqcq.xml?feed_filter=20160916Zs7Wq.html
http://www.yqcq.gov.cn/e/space/?userid=651833&yqcq.xml?feed_filter=20160916Ni7Gy.html
http://www.yqcq.gov.cn/e/space/?userid=651836&yqcq.xml?feed_filter=20160916Mi1Xx.html
http://www.yqcq.gov.cn/e/space/?userid=651839&yqcq.xml?feed_filter=20160916Dg2Jg.html
http://www.yqcq.gov.cn/e/space/?userid=651841&yqcq.xml?feed_filter=20160916Co2Ix.html
http://www.yqcq.gov.cn/e/space/?userid=651843&yqcq.xml?feed_filter=20160916Sa1Rz.html
http://www.yqcq.gov.cn/e/space/?userid=651845&yqcq.xml?feed_filter=20160916Wl7Bg.html
http://www.yqcq.gov.cn/e/space/?userid=651847&yqcq.xml?feed_filter=20160916Ot9Yk.html
http://www.yqcq.gov.cn/e/space/?userid=651850&yqcq.xml?feed_filter=20160916Ro0Ne.html
http://www.yqcq.gov.cn/e/space/?userid=651852&yqcq.xml?feed_filter=20160916Ka9Dt.html
http://www.yqcq.gov.cn/e/space/?userid=651855&yqcq.xml?feed_filter=20160916Vl5Mh.html
http://www.yqcq.gov.cn/e/space/?userid=651857&yqcq.xml?feed_filter=20160916Us5Av.html
http://www.yqcq.gov.cn/e/space/?userid=651858&yqcq.xml?feed_filter=20160916Sj4Zq.html
http://www.yqcq.gov.cn/e/space/?userid=651861&yqcq.xml?feed_filter=20160916Gm4Eb.html
http://www.yqcq.gov.cn/e/space/?userid=651862&yqcq.xml?feed_filter=20160916Uy0Ng.html
http://www.yqcq.gov.cn/e/space/?userid=651864&yqcq.xml?feed_filter=20160916Nr6Pm.html
http://www.yqcq.gov.cn/e/space/?userid=651866&yqcq.xml?feed_filter=20160916Gi7Qu.html
http://www.yqcq.gov.cn/e/space/?userid=651868&yqcq.xml?feed_filter=20160916Js4Vy.html
http://www.yqcq.gov.cn/e/space/?userid=651872&yqcq.xml?feed_filter=20160916De3Cu.html
http://www.yqcq.gov.cn/e/space/?userid=651873&yqcq.xml?feed_filter=20160916Hj3Ca.html
http://www.yqcq.gov.cn/e/space/?userid=651874&yqcq.xml?feed_filter=20160916Ft4Jc.html
http://www.yqcq.gov.cn/e/space/?userid=651876&yqcq.xml?feed_filter=20160916Rv3Ol.html
http://www.yqcq.gov.cn/e/space/?userid=651879&yqcq.xml?feed_filter=20160916Qu7Ft.html
http://www.yqcq.gov.cn/e/space/?userid=651880&yqcq.xml?feed_filter=20160916Ny5Tz.html
http://www.yqcq.gov.cn/e/space/?userid=651882&yqcq.xml?feed_filter=20160916Aa4Jv.html
http://www.yqcq.gov.cn/e/space/?userid=651884&yqcq.xml?feed_filter=20160916Iu0Tg.html
http://www.yqcq.gov.cn/e/space/?userid=651886&yqcq.xml?feed_filter=20160916Tz3Ce.html
http://www.yqcq.gov.cn/e/space/?userid=651889&yqcq.xml?feed_filter=20160916Sw8Jd.html
http://www.yqcq.gov.cn/e/space/?userid=651890&yqcq.xml?feed_filter=20160916Gb6Oj.html
http://www.yqcq.gov.cn/e/space/?userid=651892&yqcq.xml?feed_filter=20160916Zb7Xm.html
http://www.yqcq.gov.cn/e/space/?userid=651894&yqcq.xml?feed_filter=20160916Cr4Wv.html
http://www.yqcq.gov.cn/e/space/?userid=651896&yqcq.xml?feed_filter=20160916Or0Vj.html
http://www.yqcq.gov.cn/e/space/?userid=651898&yqcq.xml?feed_filter=20160916Hr8Ci.html
http://www.yqcq.gov.cn/e/space/?userid=651899&yqcq.xml?feed_filter=20160916Jg2Jt.html
http://www.yqcq.gov.cn/e/space/?userid=651903&yqcq.xml?feed_filter=20160916Xm3Ad.html
http://www.yqcq.gov.cn/e/space/?userid=651905&yqcq.xml?feed_filter=20160916Qr2Pz.html
http://www.yqcq.gov.cn/e/space/?userid=651908&yqcq.xml?feed_filter=20160916Tb1Qv.html
http://www.yqcq.gov.cn/e/space/?userid=651910&yqcq.xml?feed_filter=20160916Uo1Zg.html
http://www.yqcq.gov.cn/e/space/?userid=651914&yqcq.xml?feed_filter=20160916Vr0Qf.html
http://www.yqcq.gov.cn/e/space/?userid=651917&yqcq.xml?feed_filter=20160916Ze1Fq.html
http://www.yqcq.gov.cn/e/space/?userid=651919&yqcq.xml?feed_filter=20160916Br5Ht.html
http://www.yqcq.gov.cn/e/space/?userid=651922&yqcq.xml?feed_filter=20160916Sn0Bn.html
http://www.yqcq.gov.cn/e/space/?userid=651924&yqcq.xml?feed_filter=20160916Id7Pk.html
http://www.yqcq.gov.cn/e/space/?userid=651925&yqcq.xml?feed_filter=20160916Td7Eh.html
http://www.yqcq.gov.cn/e/space/?userid=651927&yqcq.xml?feed_filter=20160916Uu9Ro.html
http://www.yqcq.gov.cn/e/space/?userid=651929&yqcq.xml?feed_filter=20160916Uj3Wu.html
http://www.yqcq.gov.cn/e/space/?userid=651930&yqcq.xml?feed_filter=20160916Km9Gh.html
http://www.yqcq.gov.cn/e/space/?userid=651931&yqcq.xml?feed_filter=20160916Am4Jn.html
http://www.yqcq.gov.cn/e/space/?userid=651933&yqcq.xml?feed_filter=20160916Id3Iu.html
http://www.yqcq.gov.cn/e/space/?userid=651935&yqcq.xml?feed_filter=20160916La9Zy.html
http://www.yqcq.gov.cn/e/space/?userid=651936&yqcq.xml?feed_filter=20160916Yy5Nd.html
http://www.yqcq.gov.cn/e/space/?userid=651937&yqcq.xml?feed_filter=20160916Ip5Ot.html
http://www.yqcq.gov.cn/e/space/?userid=651939&yqcq.xml?feed_filter=20160916Xq7Vy.html
http://www.yqcq.gov.cn/e/space/?userid=651941&yqcq.xml?feed_filter=20160916Pg0Yo.html
http://www.yqcq.gov.cn/e/space/?userid=651945&yqcq.xml?feed_filter=20160916Xn9Uu.html
http://www.yqcq.gov.cn/e/space/?userid=651946&yqcq.xml?feed_filter=20160916Kj7Ze.html
http://www.yqcq.gov.cn/e/space/?userid=651948&yqcq.xml?feed_filter=20160916Ar8Qx.html
http://www.yqcq.gov.cn/e/space/?userid=651951&yqcq.xml?feed_filter=20160916Cb5Ev.html
http://www.yqcq.gov.cn/e/space/?userid=651953&yqcq.xml?feed_filter=20160916Lz3Xz.html
http://www.yqcq.gov.cn/e/space/?userid=651956&yqcq.xml?feed_filter=20160916Tv8Cn.html
http://www.yqcq.gov.cn/e/space/?userid=651957&yqcq.xml?feed_filter=20160916Wo1Ut.html
http://www.yqcq.gov.cn/e/space/?userid=651959&yqcq.xml?feed_filter=20160916Xw9Jx.html
http://www.yqcq.gov.cn/e/space/?userid=651962&yqcq.xml?feed_filter=20160916Hc8Zv.html
http://www.yqcq.gov.cn/e/space/?userid=651964&yqcq.xml?feed_filter=20160916Un4Wg.html
http://www.yqcq.gov.cn/e/space/?userid=651967&yqcq.xml?feed_filter=20160916Nk1Ak.html
http://www.yqcq.gov.cn/e/space/?userid=651968&yqcq.xml?feed_filter=20160916Ts8Ru.html
http://www.yqcq.gov.cn/e/space/?userid=651971&yqcq.xml?feed_filter=20160916Dg6Fs.html
http://www.yqcq.gov.cn/e/space/?userid=651973&yqcq.xml?feed_filter=20160916Ze8If.html
http://www.yqcq.gov.cn/e/space/?userid=651976&yqcq.xml?feed_filter=20160916Xk0Ij.html
http://www.yqcq.gov.cn/e/space/?userid=651978&yqcq.xml?feed_filter=20160916Qz6Ng.html
http://www.yqcq.gov.cn/e/space/?userid=651979&yqcq.xml?feed_filter=20160916Dy2Hk.html
http://www.yqcq.gov.cn/e/space/?userid=651982&yqcq.xml?feed_filter=20160916Kq7Df.html
http://www.yqcq.gov.cn/e/space/?userid=651985&yqcq.xml?feed_filter=20160916Li4Md.html
http://www.yqcq.gov.cn/e/space/?userid=651987&yqcq.xml?feed_filter=20160916Ir3Iq.html
http://www.yqcq.gov.cn/e/space/?userid=651990&yqcq.xml?feed_filter=20160916Bf5Ma.html
http://www.yqcq.gov.cn/e/space/?userid=651992&yqcq.xml?feed_filter=20160916Qr7Hr.html
http://www.yqcq.gov.cn/e/space/?userid=651993&yqcq.xml?feed_filter=20160916Rd7Fe.html
http://www.yqcq.gov.cn/e/space/?userid=651996&yqcq.xml?feed_filter=20160916Ep0Er.html
http://www.yqcq.gov.cn/e/space/?userid=651998&yqcq.xml?feed_filter=20160916Nd9Uq.html
http://www.yqcq.gov.cn/e/space/?userid=652000&yqcq.xml?feed_filter=20160916Zu9Ub.html
http://www.yqcq.gov.cn/e/space/?userid=652002&yqcq.xml?feed_filter=20160916To8Os.html
http://www.yqcq.gov.cn/e/space/?userid=652005&yqcq.xml?feed_filter=20160916Fr6Vb.html
http://www.yqcq.gov.cn/e/space/?userid=652006&yqcq.xml?feed_filter=20160916Tm4Di.html
http://www.yqcq.gov.cn/e/space/?userid=652008&yqcq.xml?feed_filter=20160916Kk9Jf.html
http://www.yqcq.gov.cn/e/space/?userid=652011&yqcq.xml?feed_filter=20160916Xv4Ng.html
http://www.yqcq.gov.cn/e/space/?userid=652013&yqcq.xml?feed_filter=20160916Lu5Dp.html
http://www.yqcq.gov.cn/e/space/?userid=652015&yqcq.xml?feed_filter=20160916Kj5Py.html
http://www.yqcq.gov.cn/e/space/?userid=652018&yqcq.xml?feed_filter=20160916Ds7Qg.html
http://www.yqcq.gov.cn/e/space/?userid=652019&yqcq.xml?feed_filter=20160916Vs7Wz.html
http://www.yqcq.gov.cn/e/space/?userid=652022&yqcq.xml?feed_filter=20160916Qd8Iv.html
http://www.yqcq.gov.cn/e/space/?userid=652024&yqcq.xml?feed_filter=20160916Yf1Ik.html
http://www.yqcq.gov.cn/e/space/?userid=652027&yqcq.xml?feed_filter=20160916Wc2Ag.html
http://www.yqcq.gov.cn/e/space/?userid=652030&yqcq.xml?feed_filter=20160916Ve6Ir.html
http://www.yqcq.gov.cn/e/space/?userid=652032&yqcq.xml?feed_filter=20160916Do2Sr.html
http://www.yqcq.gov.cn/e/space/?userid=652035&yqcq.xml?feed_filter=20160916Bs6Cq.html
http://www.yqcq.gov.cn/e/space/?userid=652037&yqcq.xml?feed_filter=20160916Pk1Um.html
http://www.yqcq.gov.cn/e/space/?userid=652040&yqcq.xml?feed_filter=20160916Yx9Qh.html
http://www.yqcq.gov.cn/e/space/?userid=652042&yqcq.xml?feed_filter=20160916Rj1Wb.html
http://www.yqcq.gov.cn/e/space/?userid=652044&yqcq.xml?feed_filter=20160916Gj2Ch.html
http://www.yqcq.gov.cn/e/space/?userid=652046&yqcq.xml?feed_filter=20160916Cs2Ap.html
http://www.yqcq.gov.cn/e/space/?userid=652047&yqcq.xml?feed_filter=20160916Vf8Cn.html
http://www.yqcq.gov.cn/e/space/?userid=652049&yqcq.xml?feed_filter=20160916Or5Sb.html
http://www.yqcq.gov.cn/e/space/?userid=652052&yqcq.xml?feed_filter=20160916We2Sn.html
http://www.yqcq.gov.cn/e/space/?userid=652053&yqcq.xml?feed_filter=20160916Fx5Yn.html
http://www.yqcq.gov.cn/e/space/?userid=652056&yqcq.xml?feed_filter=20160916Uw0Er.html
http://www.yqcq.gov.cn/e/space/?userid=652058&yqcq.xml?feed_filter=20160916Hd7Wj.html
http://www.yqcq.gov.cn/e/space/?userid=652060&yqcq.xml?feed_filter=20160916Jr7Nj.html
http://www.yqcq.gov.cn/e/space/?userid=652062&yqcq.xml?feed_filter=20160916Bs7Bg.html
http://www.yqcq.gov.cn/e/space/?userid=652065&yqcq.xml?feed_filter=20160916Ds0Fe.html
http://www.yqcq.gov.cn/e/space/?userid=652066&yqcq.xml?feed_filter=20160916Sv3Fc.html
http://www.yqcq.gov.cn/e/space/?userid=652069&yqcq.xml?feed_filter=20160916Un9Ni.html
http://www.yqcq.gov.cn/e/space/?userid=652072&yqcq.xml?feed_filter=20160916Sz7Fb.html
http://www.yqcq.gov.cn/e/space/?userid=652075&yqcq.xml?feed_filter=20160916Hx1Qp.html
http://www.yqcq.gov.cn/e/space/?userid=652077&yqcq.xml?feed_filter=20160916Jt7Co.html
http://www.yqcq.gov.cn/e/space/?userid=652079&yqcq.xml?feed_filter=20160916Ff0Ak.html
http://www.yqcq.gov.cn/e/space/?userid=652082&yqcq.xml?feed_filter=20160916Bd3Gh.html
http://www.yqcq.gov.cn/e/space/?userid=652084&yqcq.xml?feed_filter=20160916Ma7La.html
http://www.yqcq.gov.cn/e/space/?userid=652086&yqcq.xml?feed_filter=20160916Fk3Rn.html
http://www.yqcq.gov.cn/e/space/?userid=652089&yqcq.xml?feed_filter=20160916Kt3Al.html
http://www.yqcq.gov.cn/e/space/?userid=652091&yqcq.xml?feed_filter=20160916Lq5Kw.html
http://www.yqcq.gov.cn/e/space/?userid=652093&yqcq.xml?feed_filter=20160916Dl6Kt.html
http://www.yqcq.gov.cn/e/space/?userid=652095&yqcq.xml?feed_filter=20160916Ji5Ya.html
http://www.yqcq.gov.cn/e/space/?userid=652096&yqcq.xml?feed_filter=20160916Ez8Bt.html
http://www.yqcq.gov.cn/e/space/?userid=652098&yqcq.xml?feed_filter=20160916Kq0Bu.html
http://www.yqcq.gov.cn/e/space/?userid=652100&yqcq.xml?feed_filter=20160916Nn8Wv.html
http://www.yqcq.gov.cn/e/space/?userid=652102&yqcq.xml?feed_filter=20160916Bc9Mu.html
http://www.yqcq.gov.cn/e/space/?userid=652105&yqcq.xml?feed_filter=20160916Eg1Fx.html
http://www.yqcq.gov.cn/e/space/?userid=652106&yqcq.xml?feed_filter=20160916Iy5Ni.html
http://www.yqcq.gov.cn/e/space/?userid=652109&yqcq.xml?feed_filter=20160916Iw0Yx.html
http://www.yqcq.gov.cn/e/space/?userid=652110&yqcq.xml?feed_filter=20160916Vx2Gv.html
http://www.yqcq.gov.cn/e/space/?userid=652112&yqcq.xml?feed_filter=20160916Ft2Jo.html
http://www.yqcq.gov.cn/e/space/?userid=652115&yqcq.xml?feed_filter=20160916Bz2Fv.html
http://www.yqcq.gov.cn/e/space/?userid=652118&yqcq.xml?feed_filter=20160916Mw7Ga.html
http://www.yqcq.gov.cn/e/space/?userid=652121&yqcq.xml?feed_filter=20160916Gy0Ky.html
http://www.yqcq.gov.cn/e/space/?userid=652123&yqcq.xml?feed_filter=20160916Zc1Ff.html
http://www.yqcq.gov.cn/e/space/?userid=652126&yqcq.xml?feed_filter=20160916Aq5Jn.html
http://www.yqcq.gov.cn/e/space/?userid=652128&yqcq.xml?feed_filter=20160916Mx5Yb.html
http://www.yqcq.gov.cn/e/space/?userid=652130&yqcq.xml?feed_filter=20160916De0Jk.html
http://www.yqcq.gov.cn/e/space/?userid=652133&yqcq.xml?feed_filter=20160916Yv4Am.html
http://www.yqcq.gov.cn/e/space/?userid=652135&yqcq.xml?feed_filter=20160916Kw5Uc.html
http://www.yqcq.gov.cn/e/space/?userid=652136&yqcq.xml?feed_filter=20160916Df5Jx.html
http://www.yqcq.gov.cn/e/space/?userid=652138&yqcq.xml?feed_filter=20160916Ks5Fj.html
http://www.yqcq.gov.cn/e/space/?userid=652139&yqcq.xml?feed_filter=20160916Uz0Cz.html
http://www.yqcq.gov.cn/e/space/?userid=652142&yqcq.xml?feed_filter=20160916Fa1Jv.html
http://www.yqcq.gov.cn/e/space/?userid=652144&yqcq.xml?feed_filter=20160916Xo3Gj.html
http://www.yqcq.gov.cn/e/space/?userid=652147&yqcq.xml?feed_filter=20160916Xf3Al.html
http://www.yqcq.gov.cn/e/space/?userid=652149&yqcq.xml?feed_filter=20160916Sj4Tz.html
http://www.yqcq.gov.cn/e/space/?userid=652151&yqcq.xml?feed_filter=20160916Sj2Ob.html
http://www.yqcq.gov.cn/e/space/?userid=652153&yqcq.xml?feed_filter=20160916Sn5Ph.html
http://www.yqcq.gov.cn/e/space/?userid=652155&yqcq.xml?feed_filter=20160916Fb8Hc.html
http://www.yqcq.gov.cn/e/space/?userid=652157&yqcq.xml?feed_filter=20160916Jh6Ji.html
http://www.yqcq.gov.cn/e/space/?userid=652159&yqcq.xml?feed_filter=20160916On1Xa.html
http://www.yqcq.gov.cn/e/space/?userid=652161&yqcq.xml?feed_filter=20160916Ho6Ww.html
http://www.yqcq.gov.cn/e/space/?userid=652162&yqcq.xml?feed_filter=20160916Vi8Br.html
http://www.yqcq.gov.cn/e/space/?userid=652164&yqcq.xml?feed_filter=20160916Nh8Kt.html
http://www.yqcq.gov.cn/e/space/?userid=652167&yqcq.xml?feed_filter=20160916Zn3Ps.html
http://www.yqcq.gov.cn/e/space/?userid=652168&yqcq.xml?feed_filter=20160916Wg7So.html
http://www.yqcq.gov.cn/e/space/?userid=652170&yqcq.xml?feed_filter=20160916Zt6Dh.html
http://www.yqcq.gov.cn/e/space/?userid=652172&yqcq.xml?feed_filter=20160916Pk3Ij.html
http://www.yqcq.gov.cn/e/space/?userid=652174&yqcq.xml?feed_filter=20160916Rf1Cu.html
http://www.yqcq.gov.cn/e/space/?userid=652176&yqcq.xml?feed_filter=20160916Yq7Yx.html
http://www.yqcq.gov.cn/e/space/?userid=652178&yqcq.xml?feed_filter=20160916Vq3Mw.html
http://www.yqcq.gov.cn/e/space/?userid=652180&yqcq.xml?feed_filter=20160916Zl3Iw.html
http://www.yqcq.gov.cn/e/space/?userid=652182&yqcq.xml?feed_filter=20160916Mz7Ze.html
http://www.yqcq.gov.cn/e/space/?userid=652183&yqcq.xml?feed_filter=20160916Qs8Mc.html
http://www.yqcq.gov.cn/e/space/?userid=652185&yqcq.xml?feed_filter=20160916Im9Bp.html
http://www.yqcq.gov.cn/e/space/?userid=652186&yqcq.xml?feed_filter=20160916Ls1Uc.html
http://www.yqcq.gov.cn/e/space/?userid=652189&yqcq.xml?feed_filter=20160916Nk8Tf.html
http://www.yqcq.gov.cn/e/space/?userid=652192&yqcq.xml?feed_filter=20160916Lm6Eq.html
http://www.yqcq.gov.cn/e/space/?userid=652195&yqcq.xml?feed_filter=20160916Zw5Dk.html
http://www.yqcq.gov.cn/e/space/?userid=652198&yqcq.xml?feed_filter=20160916Cb6Yb.html
http://www.yqcq.gov.cn/e/space/?userid=652200&yqcq.xml?feed_filter=20160916Hf4Dw.html
http://www.yqcq.gov.cn/e/space/?userid=652204&yqcq.xml?feed_filter=20160916Qg3Zz.html
http://www.yqcq.gov.cn/e/space/?userid=652206&yqcq.xml?feed_filter=20160916Yy2Ol.html
http://www.yqcq.gov.cn/e/space/?userid=652209&yqcq.xml?feed_filter=20160916Rx4Ny.html
http://www.yqcq.gov.cn/e/space/?userid=652211&yqcq.xml?feed_filter=20160916Mo1Ea.html
http://www.yqcq.gov.cn/e/space/?userid=652214&yqcq.xml?feed_filter=20160916Od6Sb.html
http://www.yqcq.gov.cn/e/space/?userid=652216&yqcq.xml?feed_filter=20160916Di0Js.html
http://www.yqcq.gov.cn/e/space/?userid=652218&yqcq.xml?feed_filter=20160916Xz5Sk.html
http://www.yqcq.gov.cn/e/space/?userid=652220&yqcq.xml?feed_filter=20160916Rw8Fu.html
http://www.yqcq.gov.cn/e/space/?userid=652223&yqcq.xml?feed_filter=20160916Ws0Zz.html
http://www.yqcq.gov.cn/e/space/?userid=652225&yqcq.xml?feed_filter=20160916Dn3Sp.html
http://www.yqcq.gov.cn/e/space/?userid=652227&yqcq.xml?feed_filter=20160916Ej2Ph.html
http://www.yqcq.gov.cn/e/space/?userid=652230&yqcq.xml?feed_filter=20160916Fz4Fz.html
http://www.yqcq.gov.cn/e/space/?userid=652232&yqcq.xml?feed_filter=20160916Or9Gq.html
http://www.yqcq.gov.cn/e/space/?userid=652235&yqcq.xml?feed_filter=20160916Tu6Pm.html
http://www.yqcq.gov.cn/e/space/?userid=652237&yqcq.xml?feed_filter=20160916Qn6Bi.html
http://www.yqcq.gov.cn/e/space/?userid=652240&yqcq.xml?feed_filter=20160916Yr9Ok.html
http://www.yqcq.gov.cn/e/space/?userid=652242&yqcq.xml?feed_filter=20160916Yj6Ou.html
http://www.yqcq.gov.cn/e/space/?userid=652244&yqcq.xml?feed_filter=20160916Gh7Xc.html
http://www.yqcq.gov.cn/e/space/?userid=652246&yqcq.xml?feed_filter=20160916Pm1Dy.html
http://www.yqcq.gov.cn/e/space/?userid=652248&yqcq.xml?feed_filter=20160916Ym7Gv.html
http://www.yqcq.gov.cn/e/space/?userid=652251&yqcq.xml?feed_filter=20160916Tv9Qr.html
http://www.yqcq.gov.cn/e/space/?userid=652253&yqcq.xml?feed_filter=20160916By0Hd.html
http://www.yqcq.gov.cn/e/space/?userid=652254&yqcq.xml?feed_filter=20160916Qt5Jn.html
http://www.yqcq.gov.cn/e/space/?userid=652257&yqcq.xml?feed_filter=20160916Cs1Qs.html
http://www.yqcq.gov.cn/e/space/?userid=652259&yqcq.xml?feed_filter=20160916Fz8Um.html
http://www.yqcq.gov.cn/e/space/?userid=652261&yqcq.xml?feed_filter=20160916Fg3Pr.html
http://www.yqcq.gov.cn/e/space/?userid=652262&yqcq.xml?feed_filter=20160916Iq7Vf.html
http://www.yqcq.gov.cn/e/space/?userid=652265&yqcq.xml?feed_filter=20160916Sr4Ag.html
http://www.yqcq.gov.cn/e/space/?userid=652268&yqcq.xml?feed_filter=20160916Lp3Es.html
http://www.yqcq.gov.cn/e/space/?userid=652269&yqcq.xml?feed_filter=20160916Td0Vb.html
http://www.yqcq.gov.cn/e/space/?userid=652271&yqcq.xml?feed_filter=20160916Fr4Jt.html
http://www.yqcq.gov.cn/e/space/?userid=652273&yqcq.xml?feed_filter=20160916Ka2Nw.html
http://www.yqcq.gov.cn/e/space/?userid=652275&yqcq.xml?feed_filter=20160916Af4Ll.html
http://www.yqcq.gov.cn/e/space/?userid=652276&yqcq.xml?feed_filter=20160916Je7Wk.html
http://www.yqcq.gov.cn/e/space/?userid=652278&yqcq.xml?feed_filter=20160916If8Uf.html
http://www.yqcq.gov.cn/e/space/?userid=652280&yqcq.xml?feed_filter=20160916Oh5Aa.html
http://www.yqcq.gov.cn/e/space/?userid=652282&yqcq.xml?feed_filter=20160916Ia9Ss.html
http://www.yqcq.gov.cn/e/space/?userid=652283&yqcq.xml?feed_filter=20160916Te1Ji.html
http://www.yqcq.gov.cn/e/space/?userid=652287&yqcq.xml?feed_filter=20160916Bt3Xj.html
http://www.yqcq.gov.cn/e/space/?userid=652289&yqcq.xml?feed_filter=20160916Yg8Hw.html
http://www.yqcq.gov.cn/e/space/?userid=652292&yqcq.xml?feed_filter=20160916Hn9Hd.html
http://www.yqcq.gov.cn/e/space/?userid=652294&yqcq.xml?feed_filter=20160916Aa6Ms.html
http://www.yqcq.gov.cn/e/space/?userid=652296&yqcq.xml?feed_filter=20160916Ep2Uj.html
http://www.yqcq.gov.cn/e/space/?userid=652298&yqcq.xml?feed_filter=20160916Ac6Gf.html
http://www.yqcq.gov.cn/e/space/?userid=652300&yqcq.xml?feed_filter=20160916Ae4Yk.html
http://www.yqcq.gov.cn/e/space/?userid=652303&yqcq.xml?feed_filter=20160916Dj1Ys.html
http://www.yqcq.gov.cn/e/space/?userid=652304&yqcq.xml?feed_filter=20160916Up3Iv.html
http://www.yqcq.gov.cn/e/space/?userid=652307&yqcq.xml?feed_filter=20160916Zw9Rm.html
http://www.yqcq.gov.cn/e/space/?userid=652308&yqcq.xml?feed_filter=20160916Kg2So.html
http://www.yqcq.gov.cn/e/space/?userid=652311&yqcq.xml?feed_filter=20160916Ey9Ng.html
http://www.yqcq.gov.cn/e/space/?userid=652313&yqcq.xml?feed_filter=20160916Qm5Yr.html
http://www.yqcq.gov.cn/e/space/?userid=652315&yqcq.xml?feed_filter=20160916Vk3Nn.html
http://www.yqcq.gov.cn/e/space/?userid=652316&yqcq.xml?feed_filter=20160916Nm4Ag.html
http://www.yqcq.gov.cn/e/space/?userid=652319&yqcq.xml?feed_filter=20160916Wu8Hy.html
http://www.yqcq.gov.cn/e/space/?userid=652321&yqcq.xml?feed_filter=20160916Lj3Uw.html
http://www.yqcq.gov.cn/e/space/?userid=652325&yqcq.xml?feed_filter=20160916Vn9Vk.html
http://www.yqcq.gov.cn/e/space/?userid=652326&yqcq.xml?feed_filter=20160916Pc9Em.html
http://www.yqcq.gov.cn/e/space/?userid=652327&yqcq.xml?feed_filter=20160916Dp0Be.html
http://www.yqcq.gov.cn/e/space/?userid=652330&yqcq.xml?feed_filter=20160916Gg2Gg.html
http://www.yqcq.gov.cn/e/space/?userid=652331&yqcq.xml?feed_filter=20160916Pz4Ya.html
http://www.yqcq.gov.cn/e/space/?userid=652333&yqcq.xml?feed_filter=20160916Lo7Yg.html
http://www.yqcq.gov.cn/e/space/?userid=652335&yqcq.xml?feed_filter=20160916Vt7Wa.html
http://www.yqcq.gov.cn/e/space/?userid=652338&yqcq.xml?feed_filter=20160916Yr5Gw.html
http://www.yqcq.gov.cn/e/space/?userid=652339&yqcq.xml?feed_filter=20160916Ty6Et.html
http://www.yqcq.gov.cn/e/space/?userid=652342&yqcq.xml?feed_filter=20160916Yd9Bh.html
http://www.yqcq.gov.cn/e/space/?userid=652344&yqcq.xml?feed_filter=20160916Xj8Xf.html
http://www.yqcq.gov.cn/e/space/?userid=652347&yqcq.xml?feed_filter=20160916Cz3Fn.html
http://www.yqcq.gov.cn/e/space/?userid=652349&yqcq.xml?feed_filter=20160916Jf5Nm.html
http://www.yqcq.gov.cn/e/space/?userid=652351&yqcq.xml?feed_filter=20160916Ev9Fo.html
http://www.yqcq.gov.cn/e/space/?userid=652352&yqcq.xml?feed_filter=20160916Ub6Tb.html
http://www.yqcq.gov.cn/e/space/?userid=652354&yqcq.xml?feed_filter=20160916Yz9Qf.html
http://www.yqcq.gov.cn/e/space/?userid=652357&yqcq.xml?feed_filter=20160916Nf8Kg.html
http://www.yqcq.gov.cn/e/space/?userid=652359&yqcq.xml?feed_filter=20160916Ri5Dt.html
http://www.yqcq.gov.cn/e/space/?userid=652361&yqcq.xml?feed_filter=20160916Uq1Ba.html
http://www.yqcq.gov.cn/e/space/?userid=652364&yqcq.xml?feed_filter=20160916Lr5Fu.html
http://www.yqcq.gov.cn/e/space/?userid=652366&yqcq.xml?feed_filter=20160916Jd4Bh.html
http://www.yqcq.gov.cn/e/space/?userid=652369&yqcq.xml?feed_filter=20160916Pk9Om.html
http://www.yqcq.gov.cn/e/space/?userid=652370&yqcq.xml?feed_filter=20160916Zb2Sl.html
http://www.yqcq.gov.cn/e/space/?userid=652373&yqcq.xml?feed_filter=20160916Ly3Pz.html
http://www.yqcq.gov.cn/e/space/?userid=652375&yqcq.xml?feed_filter=20160916Kr3Zh.html
http://www.yqcq.gov.cn/e/space/?userid=652377&yqcq.xml?feed_filter=20160916Vn7Wx.html
http://www.yqcq.gov.cn/e/space/?userid=652380&yqcq.xml?feed_filter=20160916Cu4Il.html
http://www.yqcq.gov.cn/e/space/?userid=652381&yqcq.xml?feed_filter=20160916Gk4So.html
http://www.yqcq.gov.cn/e/space/?userid=652383&yqcq.xml?feed_filter=20160916Qt0Jv.html
http://www.yqcq.gov.cn/e/space/?userid=652385&yqcq.xml?feed_filter=20160916Uf3Bw.html
http://www.yqcq.gov.cn/e/space/?userid=652387&yqcq.xml?feed_filter=20160916Md3Ey.html
http://www.yqcq.gov.cn/e/space/?userid=652389&yqcq.xml?feed_filter=20160916Th1Wx.html
http://www.yqcq.gov.cn/e/space/?userid=652392&yqcq.xml?feed_filter=20160916Aj5Zy.html
http://www.yqcq.gov.cn/e/space/?userid=652393&yqcq.xml?feed_filter=20160916Tj2Yv.html
http://www.yqcq.gov.cn/e/space/?userid=652394&yqcq.xml?feed_filter=20160916Vf3Ud.html
http://www.yqcq.gov.cn/e/space/?userid=652396&yqcq.xml?feed_filter=20160916Xo6Lw.html
http://www.yqcq.gov.cn/e/space/?userid=652398&yqcq.xml?feed_filter=20160916Nu6Te.html
http://www.yqcq.gov.cn/e/space/?userid=652401&yqcq.xml?feed_filter=20160916Kb8Eq.html
http://www.yqcq.gov.cn/e/space/?userid=652402&yqcq.xml?feed_filter=20160916Nr5Eh.html
http://www.yqcq.gov.cn/e/space/?userid=652404&yqcq.xml?feed_filter=20160916Wc1Ht.html
http://www.yqcq.gov.cn/e/space/?userid=652406&yqcq.xml?feed_filter=20160916Bj2Mx.html
http://www.yqcq.gov.cn/e/space/?userid=652407&yqcq.xml?feed_filter=20160916Jo5Do.html
http://www.yqcq.gov.cn/e/space/?userid=652409&yqcq.xml?feed_filter=20160916Hp7Nw.html
http://www.yqcq.gov.cn/e/space/?userid=652412&yqcq.xml?feed_filter=20160916Rv1Mc.html
http://www.yqcq.gov.cn/e/space/?userid=652413&yqcq.xml?feed_filter=20160916Yi0Sk.html
http://www.yqcq.gov.cn/e/space/?userid=652414&yqcq.xml?feed_filter=20160916Jy0Pa.html
http://www.yqcq.gov.cn/e/space/?userid=652417&yqcq.xml?feed_filter=20160916Mr3Wm.html
http://www.yqcq.gov.cn/e/space/?userid=652418&yqcq.xml?feed_filter=20160916Cr2Xo.html
http://www.yqcq.gov.cn/e/space/?userid=652421&yqcq.xml?feed_filter=20160916Ck2Xi.html
http://www.yqcq.gov.cn/e/space/?userid=652423&yqcq.xml?feed_filter=20160916Jd6Xe.html
http://www.yqcq.gov.cn/e/space/?userid=652426&yqcq.xml?feed_filter=20160916Ua5Zz.html
http://www.yqcq.gov.cn/e/space/?userid=652428&yqcq.xml?feed_filter=20160916Fp3Gh.html
http://www.yqcq.gov.cn/e/space/?userid=652430&yqcq.xml?feed_filter=20160916Gb2Rx.html
http://www.yqcq.gov.cn/e/space/?userid=652433&yqcq.xml?feed_filter=20160916Jh7Mh.html
http://www.yqcq.gov.cn/e/space/?userid=652436&yqcq.xml?feed_filter=20160916Hw9Zi.html
http://www.yqcq.gov.cn/e/space/?userid=652437&yqcq.xml?feed_filter=20160916Mm1Us.html
http://www.yqcq.gov.cn/e/space/?userid=652439&yqcq.xml?feed_filter=20160916Fl1Sn.html
http://www.yqcq.gov.cn/e/space/?userid=652442&yqcq.xml?feed_filter=20160916Ro0Pl.html
http://www.yqcq.gov.cn/e/space/?userid=652444&yqcq.xml?feed_filter=20160916Im9Gq.html
http://www.yqcq.gov.cn/e/space/?userid=652447&yqcq.xml?feed_filter=20160916Fg0Ny.html
http://www.yqcq.gov.cn/e/space/?userid=652449&yqcq.xml?feed_filter=20160916Bb6It.html
http://www.yqcq.gov.cn/e/space/?userid=652451&yqcq.xml?feed_filter=20160916Sc7Vo.html
http://www.yqcq.gov.cn/e/space/?userid=652453&yqcq.xml?feed_filter=20160916Ib6On.html
http://www.yqcq.gov.cn/e/space/?userid=652455&yqcq.xml?feed_filter=20160916Gv2Jz.html
http://www.yqcq.gov.cn/e/space/?userid=652459&yqcq.xml?feed_filter=20160916Jq7Qp.html
http://www.yqcq.gov.cn/e/space/?userid=652461&yqcq.xml?feed_filter=20160916Iu2Tt.html
http://www.yqcq.gov.cn/e/space/?userid=652463&yqcq.xml?feed_filter=20160916Xs0Se.html
http://www.yqcq.gov.cn/e/space/?userid=652467&yqcq.xml?feed_filter=20160916Ye0Kj.html
http://www.yqcq.gov.cn/e/space/?userid=652470&yqcq.xml?feed_filter=20160916Uj0Ma.html
http://www.yqcq.gov.cn/e/space/?userid=652471&yqcq.xml?feed_filter=20160916Sk5Ex.html
http://www.yqcq.gov.cn/e/space/?userid=652472&yqcq.xml?feed_filter=20160916Nm2Lv.html
http://www.yqcq.gov.cn/e/space/?userid=652475&yqcq.xml?feed_filter=20160916Le3Ck.html
http://www.yqcq.gov.cn/e/space/?userid=652477&yqcq.xml?feed_filter=20160916Wp6Tz.html
http://www.yqcq.gov.cn/e/space/?userid=652479&yqcq.xml?feed_filter=20160916Rx6Am.html
http://www.yqcq.gov.cn/e/space/?userid=652480&yqcq.xml?feed_filter=20160916Vu5Vi.html
http://www.yqcq.gov.cn/e/space/?userid=652482&yqcq.xml?feed_filter=20160916Bt9Pz.html
http://www.yqcq.gov.cn/e/space/?userid=652483&yqcq.xml?feed_filter=20160916Hz0Yc.html
http://www.yqcq.gov.cn/e/space/?userid=652485&yqcq.xml?feed_filter=20160916Rz1Vs.html
http://www.yqcq.gov.cn/e/space/?userid=652486&yqcq.xml?feed_filter=20160916Oz5Qz.html
http://www.yqcq.gov.cn/e/space/?userid=652488&yqcq.xml?feed_filter=20160916Rv4Sb.html
http://www.yqcq.gov.cn/e/space/?userid=652490&yqcq.xml?feed_filter=20160916Au7Vr.html
http://www.yqcq.gov.cn/e/space/?userid=652491&yqcq.xml?feed_filter=20160916Qy1Ws.html
http://www.yqcq.gov.cn/e/space/?userid=652492&yqcq.xml?feed_filter=20160916St8Rw.html
http://www.yqcq.gov.cn/e/space/?userid=652493&yqcq.xml?feed_filter=20160916Gj3Fx.html
http://www.yqcq.gov.cn/e/space/?userid=652495&yqcq.xml?feed_filter=20160916Hq6Ia.html
http://www.yqcq.gov.cn/e/space/?userid=652497&yqcq.xml?feed_filter=20160916Hw8It.html
http://www.yqcq.gov.cn/e/space/?userid=652500&yqcq.xml?feed_filter=20160916Be0Zr.html
http://www.yqcq.gov.cn/e/space/?userid=652501&yqcq.xml?feed_filter=20160916Yo9Zb.html
http://www.yqcq.gov.cn/e/space/?userid=652503&yqcq.xml?feed_filter=20160916Co4Yv.html
http://www.yqcq.gov.cn/e/space/?userid=652505&yqcq.xml?feed_filter=20160916Xz0Bn.html
http://www.yqcq.gov.cn/e/space/?userid=652506&yqcq.xml?feed_filter=20160916Gz8Jn.html
http://www.yqcq.gov.cn/e/space/?userid=652508&yqcq.xml?feed_filter=20160916Ms2Il.html
http://www.yqcq.gov.cn/e/space/?userid=652509&yqcq.xml?feed_filter=20160916Dk2Wg.html
http://www.yqcq.gov.cn/e/space/?userid=652511&yqcq.xml?feed_filter=20160916Eb4Hi.html
http://www.yqcq.gov.cn/e/space/?userid=652512&yqcq.xml?feed_filter=20160916Sm7Ni.html
http://www.yqcq.gov.cn/e/space/?userid=652515&yqcq.xml?feed_filter=20160916Gj4Gk.html
http://www.yqcq.gov.cn/e/space/?userid=652518&yqcq.xml?feed_filter=20160916Wg6Wl.html
http://www.yqcq.gov.cn/e/space/?userid=652520&yqcq.xml?feed_filter=20160916Kj7Zz.html
http://www.yqcq.gov.cn/e/space/?userid=652523&yqcq.xml?feed_filter=20160916Te3Py.html
http://www.yqcq.gov.cn/e/space/?userid=652525&yqcq.xml?feed_filter=20160916Ae2Lk.html
http://www.yqcq.gov.cn/e/space/?userid=652528&yqcq.xml?feed_filter=20160916Bz7Wn.html
http://www.yqcq.gov.cn/e/space/?userid=652530&yqcq.xml?feed_filter=20160916Iz9Yz.html
http://www.yqcq.gov.cn/e/space/?userid=652532&yqcq.xml?feed_filter=20160916Dq1Za.html
http://www.yqcq.gov.cn/e/space/?userid=652534&yqcq.xml?feed_filter=20160916Gi0Bw.html
http://www.yqcq.gov.cn/e/space/?userid=652537&yqcq.xml?feed_filter=20160916Xi9Qh.html
http://www.yqcq.gov.cn/e/space/?userid=652538&yqcq.xml?feed_filter=20160916Ee9Cu.html
http://www.yqcq.gov.cn/e/space/?userid=652542&yqcq.xml?feed_filter=20160916Ns8Er.html
http://www.yqcq.gov.cn/e/space/?userid=652545&yqcq.xml?feed_filter=20160916Gd6We.html
http://www.yqcq.gov.cn/e/space/?userid=652547&yqcq.xml?feed_filter=20160916Cl6Vf.html
http://www.yqcq.gov.cn/e/space/?userid=652549&yqcq.xml?feed_filter=20160916Sr9Pj.html
http://www.yqcq.gov.cn/e/space/?userid=652552&yqcq.xml?feed_filter=20160916Aq0Vv.html
http://www.yqcq.gov.cn/e/space/?userid=652555&yqcq.xml?feed_filter=20160916Od2Tu.html
http://www.yqcq.gov.cn/e/space/?userid=652557&yqcq.xml?feed_filter=20160916Nl1Cb.html
http://www.yqcq.gov.cn/e/space/?userid=652559&yqcq.xml?feed_filter=20160916Wc3Us.html
http://www.yqcq.gov.cn/e/space/?userid=652561&yqcq.xml?feed_filter=20160916Oh1Mr.html
http://www.yqcq.gov.cn/e/space/?userid=652564&yqcq.xml?feed_filter=20160916Vz8Cw.html
http://www.yqcq.gov.cn/e/space/?userid=652565&yqcq.xml?feed_filter=20160916Wu9Ms.html
http://www.yqcq.gov.cn/e/space/?userid=652566&yqcq.xml?feed_filter=20160916Iv9Cn.html
http://www.yqcq.gov.cn/e/space/?userid=652568&yqcq.xml?feed_filter=20160916Iy0Ld.html
http://www.yqcq.gov.cn/e/space/?userid=652569&yqcq.xml?feed_filter=20160916Nw6Ti.html
http://www.yqcq.gov.cn/e/space/?userid=652571&yqcq.xml?feed_filter=20160916Jy0Hf.html
http://www.yqcq.gov.cn/e/space/?userid=652573&yqcq.xml?feed_filter=20160916Cu7Vd.html
http://www.yqcq.gov.cn/e/space/?userid=652574&yqcq.xml?feed_filter=20160916Er9Hj.html
http://www.yqcq.gov.cn/e/space/?userid=652576&yqcq.xml?feed_filter=20160916Ik1Vc.html
http://www.yqcq.gov.cn/e/space/?userid=652578&yqcq.xml?feed_filter=20160916Cd0Fc.html
http://www.yqcq.gov.cn/e/space/?userid=652579&yqcq.xml?feed_filter=20160916Nm7Dx.html
http://www.yqcq.gov.cn/e/space/?userid=652582&yqcq.xml?feed_filter=20160916Im8Zj.html
http://www.yqcq.gov.cn/e/space/?userid=652583&yqcq.xml?feed_filter=20160916Ln0Nv.html
http://www.yqcq.gov.cn/e/space/?userid=652585&yqcq.xml?feed_filter=20160916Vz0Zl.html
http://www.yqcq.gov.cn/e/space/?userid=652587&yqcq.xml?feed_filter=20160916Gc0Hv.html
http://www.yqcq.gov.cn/e/space/?userid=652588&yqcq.xml?feed_filter=20160916Rw9Jn.html
http://www.yqcq.gov.cn/e/space/?userid=652591&yqcq.xml?feed_filter=20160916Vm1Fj.html
http://www.yqcq.gov.cn/e/space/?userid=652593&yqcq.xml?feed_filter=20160916Ac7Vl.html
http://www.yqcq.gov.cn/e/space/?userid=652594&yqcq.xml?feed_filter=20160916Pk2Ef.html
http://www.yqcq.gov.cn/e/space/?userid=652597&yqcq.xml?feed_filter=20160916Kb2Mf.html
http://www.yqcq.gov.cn/e/space/?userid=652600&yqcq.xml?feed_filter=20160916Qw2Ub.html
http://www.yqcq.gov.cn/e/space/?userid=652601&yqcq.xml?feed_filter=20160916En1Om.html
http://www.yqcq.gov.cn/e/space/?userid=652603&yqcq.xml?feed_filter=20160916Wz5Qm.html
http://www.yqcq.gov.cn/e/space/?userid=652604&yqcq.xml?feed_filter=20160916By9Uw.html
http://www.yqcq.gov.cn/e/space/?userid=652607&yqcq.xml?feed_filter=20160916Pq8Rk.html
http://www.yqcq.gov.cn/e/space/?userid=652609&yqcq.xml?feed_filter=20160916Zu8Td.html
http://www.yqcq.gov.cn/e/space/?userid=652611&yqcq.xml?feed_filter=20160916Ey6Xx.html
http://www.yqcq.gov.cn/e/space/?userid=652614&yqcq.xml?feed_filter=20160916Es7Jc.html
http://www.yqcq.gov.cn/e/space/?userid=652617&yqcq.xml?feed_filter=20160916Ux8Ik.html
http://www.yqcq.gov.cn/e/space/?userid=652620&yqcq.xml?feed_filter=20160916Sh9Ml.html
http://www.yqcq.gov.cn/e/space/?userid=652622&yqcq.xml?feed_filter=20160916Jn0Ge.html
http://www.yqcq.gov.cn/e/space/?userid=652624&yqcq.xml?feed_filter=20160916Iw4Ic.html
http://www.yqcq.gov.cn/e/space/?userid=652626&yqcq.xml?feed_filter=20160916Pu6Ff.html
http://www.yqcq.gov.cn/e/space/?userid=652628&yqcq.xml?feed_filter=20160916Ix9Rg.html
http://www.yqcq.gov.cn/e/space/?userid=652631&yqcq.xml?feed_filter=20160916Gu3Eh.html
http://www.yqcq.gov.cn/e/space/?userid=652632&yqcq.xml?feed_filter=20160916Il5Kc.html
http://www.yqcq.gov.cn/e/space/?userid=652635&yqcq.xml?feed_filter=20160916Ws4Eg.html
http://www.yqcq.gov.cn/e/space/?userid=652637&yqcq.xml?feed_filter=20160916Tr0Vi.html
http://www.yqcq.gov.cn/e/space/?userid=652640&yqcq.xml?feed_filter=20160916Sj4Xa.html
http://www.yqcq.gov.cn/e/space/?userid=652642&yqcq.xml?feed_filter=20160916Cm3Jy.html
http://www.yqcq.gov.cn/e/space/?userid=652645&yqcq.xml?feed_filter=20160916Nt5Ix.html
http://www.yqcq.gov.cn/e/space/?userid=652646&yqcq.xml?feed_filter=20160916Rv6Kw.html
http://www.yqcq.gov.cn/e/space/?userid=652649&yqcq.xml?feed_filter=20160916Vj4Zn.html
http://www.yqcq.gov.cn/e/space/?userid=652651&yqcq.xml?feed_filter=20160916Ua6Zp.html
http://www.yqcq.gov.cn/e/space/?userid=652653&yqcq.xml?feed_filter=20160916Mz9Eq.html
http://www.yqcq.gov.cn/e/space/?userid=652654&yqcq.xml?feed_filter=20160916Yc2Qp.html
http://www.yqcq.gov.cn/e/space/?userid=652657&yqcq.xml?feed_filter=20160916Vz2Ri.html
http://www.yqcq.gov.cn/e/space/?userid=652659&yqcq.xml?feed_filter=20160916Jl0Kw.html
http://www.yqcq.gov.cn/e/space/?userid=652661&yqcq.xml?feed_filter=20160916An1Cx.html
http://www.yqcq.gov.cn/e/space/?userid=652663&yqcq.xml?feed_filter=20160916Ry9Bb.html
http://www.yqcq.gov.cn/e/space/?userid=652666&yqcq.xml?feed_filter=20160916Nr9Ei.html
http://www.yqcq.gov.cn/e/space/?userid=652667&yqcq.xml?feed_filter=20160916Yl3Gs.html
http://www.yqcq.gov.cn/e/space/?userid=652669&yqcq.xml?feed_filter=20160916Zu8Rs.html
http://www.yqcq.gov.cn/e/space/?userid=652671&yqcq.xml?feed_filter=20160916Rv1Ty.html
http://www.yqcq.gov.cn/e/space/?userid=652675&yqcq.xml?feed_filter=20160916Us4Ix.html
http://www.yqcq.gov.cn/e/space/?userid=652678&yqcq.xml?feed_filter=20160916Ld6Lx.html
http://www.yqcq.gov.cn/e/space/?userid=652679&yqcq.xml?feed_filter=20160916Je0Yx.html
http://www.yqcq.gov.cn/e/space/?userid=652682&yqcq.xml?feed_filter=20160916Qq4In.html
http://www.yqcq.gov.cn/e/space/?userid=652683&yqcq.xml?feed_filter=20160916Sv5Br.html
http://www.yqcq.gov.cn/e/space/?userid=652685&yqcq.xml?feed_filter=20160916Sl0Yt.html
http://www.yqcq.gov.cn/e/space/?userid=652687&yqcq.xml?feed_filter=20160916Jd1Dv.html
http://www.yqcq.gov.cn/e/space/?userid=652688&yqcq.xml?feed_filter=20160916Ns7Fd.html
http://www.yqcq.gov.cn/e/space/?userid=652691&yqcq.xml?feed_filter=20160916Vy3Qd.html
http://www.yqcq.gov.cn/e/space/?userid=652693&yqcq.xml?feed_filter=20160916Ig5Hk.html
http://www.yqcq.gov.cn/e/space/?userid=652694&yqcq.xml?feed_filter=20160916Yc8Yq.html
http://www.yqcq.gov.cn/e/space/?userid=652697&yqcq.xml?feed_filter=20160916Hq7Ia.html
http://www.yqcq.gov.cn/e/space/?userid=652699&yqcq.xml?feed_filter=20160916Qd8Ec.html
http://www.yqcq.gov.cn/e/space/?userid=652702&yqcq.xml?feed_filter=20160916Ml4Cn.html
http://www.yqcq.gov.cn/e/space/?userid=652704&yqcq.xml?feed_filter=20160916Yu2Pb.html
http://www.yqcq.gov.cn/e/space/?userid=652706&yqcq.xml?feed_filter=20160916Ek4Uw.html
http://www.yqcq.gov.cn/e/space/?userid=652710&yqcq.xml?feed_filter=20160916Zb9Zs.html
http://www.yqcq.gov.cn/e/space/?userid=652712&yqcq.xml?feed_filter=20160916Ie8In.html
http://www.yqcq.gov.cn/e/space/?userid=652715&yqcq.xml?feed_filter=20160916Az5Vx.html
http://www.yqcq.gov.cn/e/space/?userid=652718&yqcq.xml?feed_filter=20160916Eg5Ey.html
http://www.yqcq.gov.cn/e/space/?userid=652719&yqcq.xml?feed_filter=20160916Ra4Nx.html
http://www.yqcq.gov.cn/e/space/?userid=652722&yqcq.xml?feed_filter=20160916Mt3Ok.html
http://www.yqcq.gov.cn/e/space/?userid=652726&yqcq.xml?feed_filter=20160916Ic9Fm.html
http://www.yqcq.gov.cn/e/space/?userid=652727&yqcq.xml?feed_filter=20160916Go0Op.html
http://www.yqcq.gov.cn/e/space/?userid=652730&yqcq.xml?feed_filter=20160916Xs7Du.html
http://www.yqcq.gov.cn/e/space/?userid=652732&yqcq.xml?feed_filter=20160916Lz7Ih.html
http://www.yqcq.gov.cn/e/space/?userid=652734&yqcq.xml?feed_filter=20160916Gf9Bi.html
http://www.yqcq.gov.cn/e/space/?userid=652737&yqcq.xml?feed_filter=20160916Ip5Oj.html
http://www.yqcq.gov.cn/e/space/?userid=652739&yqcq.xml?feed_filter=20160916Cf3Xo.html
http://www.yqcq.gov.cn/e/space/?userid=652741&yqcq.xml?feed_filter=20160916Cd5Iu.html
http://www.yqcq.gov.cn/e/space/?userid=652744&yqcq.xml?feed_filter=20160916Xc9Al.html
http://www.yqcq.gov.cn/e/space/?userid=652746&yqcq.xml?feed_filter=20160916Si1Hq.html
http://www.yqcq.gov.cn/e/space/?userid=652749&yqcq.xml?feed_filter=20160916Fj7Er.html
http://www.yqcq.gov.cn/e/space/?userid=652752&yqcq.xml?feed_filter=20160916Aj1Bt.html
http://www.yqcq.gov.cn/e/space/?userid=652753&yqcq.xml?feed_filter=20160916Im2Ts.html
http://www.yqcq.gov.cn/e/space/?userid=652756&yqcq.xml?feed_filter=20160916Uj5Pr.html
http://www.yqcq.gov.cn/e/space/?userid=652758&yqcq.xml?feed_filter=20160916Pa2Tb.html
http://www.yqcq.gov.cn/e/space/?userid=652762&yqcq.xml?feed_filter=20160916Yp3Ou.html
http://www.yqcq.gov.cn/e/space/?userid=652763&yqcq.xml?feed_filter=20160916Qw1Lc.html
http://www.yqcq.gov.cn/e/space/?userid=652766&yqcq.xml?feed_filter=20160916Qb7Ju.html
http://www.yqcq.gov.cn/e/space/?userid=652769&yqcq.xml?feed_filter=20160916Pj2Ov.html
http://www.yqcq.gov.cn/e/space/?userid=652770&yqcq.xml?feed_filter=20160916Ha9Hr.html
http://www.yqcq.gov.cn/e/space/?userid=652772&yqcq.xml?feed_filter=20160916No3Pe.html
http://www.yqcq.gov.cn/e/space/?userid=652775&yqcq.xml?feed_filter=20160916Cg1Cp.html
http://www.yqcq.gov.cn/e/space/?userid=652777&yqcq.xml?feed_filter=20160916Ve5Lo.html
http://www.yqcq.gov.cn/e/space/?userid=652780&yqcq.xml?feed_filter=20160916Kw9Zc.html
http://www.yqcq.gov.cn/e/space/?userid=652782&yqcq.xml?feed_filter=20160916Dk9Ym.html
http://www.yqcq.gov.cn/e/space/?userid=652785&yqcq.xml?feed_filter=20160916Hk2Fm.html
http://www.yqcq.gov.cn/e/space/?userid=652787&yqcq.xml?feed_filter=20160916Zc1Jq.html
http://www.yqcq.gov.cn/e/space/?userid=652788&yqcq.xml?feed_filter=20160916Hs3Ku.html
http://www.yqcq.gov.cn/e/space/?userid=652792&yqcq.xml?feed_filter=20160916Ud2Ai.html
http://www.yqcq.gov.cn/e/space/?userid=652794&yqcq.xml?feed_filter=20160916Hi3Bx.html
http://www.yqcq.gov.cn/e/space/?userid=652796&yqcq.xml?feed_filter=20160916Kl1Lj.html
http://www.yqcq.gov.cn/e/space/?userid=652799&yqcq.xml?feed_filter=20160916Aj8Qt.html
http://www.yqcq.gov.cn/e/space/?userid=652802&yqcq.xml?feed_filter=20160916Be3Yz.html
http://www.yqcq.gov.cn/e/space/?userid=652804&yqcq.xml?feed_filter=20160916Zd4Ra.html
http://www.yqcq.gov.cn/e/space/?userid=652806&yqcq.xml?feed_filter=20160916Tx2Ze.html
http://www.yqcq.gov.cn/e/space/?userid=652807&yqcq.xml?feed_filter=20160916Ik6El.html
http://www.yqcq.gov.cn/e/space/?userid=652810&yqcq.xml?feed_filter=20160916Ff4Uz.html
http://www.yqcq.gov.cn/e/space/?userid=652812&yqcq.xml?feed_filter=20160916Ja3Ii.html
http://www.yqcq.gov.cn/e/space/?userid=652814&yqcq.xml?feed_filter=20160916Ao6Lq.html
http://www.yqcq.gov.cn/e/space/?userid=652817&yqcq.xml?feed_filter=20160916Oc8Jf.html
http://www.yqcq.gov.cn/e/space/?userid=652819&yqcq.xml?feed_filter=20160916Cu7Vr.html
http://www.yqcq.gov.cn/e/space/?userid=652822&yqcq.xml?feed_filter=20160916Rz9Kg.html
http://www.yqcq.gov.cn/e/space/?userid=652824&yqcq.xml?feed_filter=20160916No2Wv.html
http://www.yqcq.gov.cn/e/space/?userid=652825&yqcq.xml?feed_filter=20160916Ko2Rm.html
http://www.yqcq.gov.cn/e/space/?userid=652828&yqcq.xml?feed_filter=20160916Bo5Jn.html
http://www.yqcq.gov.cn/e/space/?userid=652831&yqcq.xml?feed_filter=20160916Zy1Xg.html
http://www.yqcq.gov.cn/e/space/?userid=652832&yqcq.xml?feed_filter=20160916Hd8Hk.html
http://www.yqcq.gov.cn/e/space/?userid=652835&yqcq.xml?feed_filter=20160916Pd3Ww.html
http://www.yqcq.gov.cn/e/space/?userid=652839&yqcq.xml?feed_filter=20160916Ws9Iy.html
http://www.yqcq.gov.cn/e/space/?userid=652841&yqcq.xml?feed_filter=20160916Tx7Om.html
http://www.yqcq.gov.cn/e/space/?userid=652843&yqcq.xml?feed_filter=20160916Gc6Kr.html
http://www.yqcq.gov.cn/e/space/?userid=652846&yqcq.xml?feed_filter=20160916Dn0Ko.html
http://www.yqcq.gov.cn/e/space/?userid=652848&yqcq.xml?feed_filter=20160916Po3Mb.html
http://www.yqcq.gov.cn/e/space/?userid=652849&yqcq.xml?feed_filter=20160916Tn5Pt.html
http://www.yqcq.gov.cn/e/space/?userid=652852&yqcq.xml?feed_filter=20160916Fp3Ri.html
http://www.yqcq.gov.cn/e/space/?userid=652855&yqcq.xml?feed_filter=20160916Uu2Pd.html
http://www.yqcq.gov.cn/e/space/?userid=652857&yqcq.xml?feed_filter=20160916Bg7Hn.html
http://www.yqcq.gov.cn/e/space/?userid=652859&yqcq.xml?feed_filter=20160916Mb5Ne.html
http://www.yqcq.gov.cn/e/space/?userid=652861&yqcq.xml?feed_filter=20160916Rf2Bu.html
http://www.yqcq.gov.cn/e/space/?userid=652862&yqcq.xml?feed_filter=20160916Fj2Rs.html
http://www.yqcq.gov.cn/e/space/?userid=652863&yqcq.xml?feed_filter=20160916Xf6Nx.html
http://www.yqcq.gov.cn/e/space/?userid=652864&yqcq.xml?feed_filter=20160916Ad9Nf.html
http://www.yqcq.gov.cn/e/space/?userid=652866&yqcq.xml?feed_filter=20160916Cj0Jy.html
http://www.yqcq.gov.cn/e/space/?userid=652868&yqcq.xml?feed_filter=20160916Ve1Ha.html
http://www.yqcq.gov.cn/e/space/?userid=652869&yqcq.xml?feed_filter=20160916Qw8Be.html
http://www.yqcq.gov.cn/e/space/?userid=652871&yqcq.xml?feed_filter=20160916Ot5Ji.html
http://www.yqcq.gov.cn/e/space/?userid=652873&yqcq.xml?feed_filter=20160916Ah9Xw.html
http://www.yqcq.gov.cn/e/space/?userid=652875&yqcq.xml?feed_filter=20160916Gc1Hk.html
http://www.yqcq.gov.cn/e/space/?userid=652877&yqcq.xml?feed_filter=20160916Gx8He.html
http://www.yqcq.gov.cn/e/space/?userid=652879&yqcq.xml?feed_filter=20160916Le3Rs.html
http://www.yqcq.gov.cn/e/space/?userid=652880&yqcq.xml?feed_filter=20160916Yt5Lo.html
http://www.yqcq.gov.cn/e/space/?userid=652883&yqcq.xml?feed_filter=20160916Qa1Ry.html
http://www.yqcq.gov.cn/e/space/?userid=652885&yqcq.xml?feed_filter=20160916Xw9Cq.html
http://www.yqcq.gov.cn/e/space/?userid=652887&yqcq.xml?feed_filter=20160916Xb8Ob.html
http://www.yqcq.gov.cn/e/space/?userid=652889&yqcq.xml?feed_filter=20160916Rr0Aj.html
http://www.yqcq.gov.cn/e/space/?userid=652891&yqcq.xml?feed_filter=20160916Yu2Ib.html
http://www.yqcq.gov.cn/e/space/?userid=652893&yqcq.xml?feed_filter=20160916Xk1Er.html
http://www.yqcq.gov.cn/e/space/?userid=652894&yqcq.xml?feed_filter=20160916Qi3Wi.html
http://www.yqcq.gov.cn/e/space/?userid=652897&yqcq.xml?feed_filter=20160916Jw3Jy.html
http://www.yqcq.gov.cn/e/space/?userid=652898&yqcq.xml?feed_filter=20160916Pi4Xr.html
http://www.yqcq.gov.cn/e/space/?userid=652900&yqcq.xml?feed_filter=20160916Va4Lh.html
http://www.yqcq.gov.cn/e/space/?userid=652902&yqcq.xml?feed_filter=20160916Es0Dm.html
http://www.yqcq.gov.cn/e/space/?userid=652904&yqcq.xml?feed_filter=20160916Gv5Ma.html
http://www.yqcq.gov.cn/e/space/?userid=652905&yqcq.xml?feed_filter=20160916Xd1Or.html
http://www.yqcq.gov.cn/e/space/?userid=652907&yqcq.xml?feed_filter=20160916Ys7Zi.html
http://www.yqcq.gov.cn/e/space/?userid=652910&yqcq.xml?feed_filter=20160916Yr6Xl.html
http://www.yqcq.gov.cn/e/space/?userid=652912&yqcq.xml?feed_filter=20160916Ba4Vu.html
http://www.yqcq.gov.cn/e/space/?userid=652914&yqcq.xml?feed_filter=20160916Qe0Zp.html
http://www.yqcq.gov.cn/e/space/?userid=652918&yqcq.xml?feed_filter=20160916Cq5Gn.html
http://www.yqcq.gov.cn/e/space/?userid=652919&yqcq.xml?feed_filter=20160916Tr9Ox.html
http://www.yqcq.gov.cn/e/space/?userid=652922&yqcq.xml?feed_filter=20160916Sk1Tv.html
http://www.yqcq.gov.cn/e/space/?userid=652923&yqcq.xml?feed_filter=20160916Df5Bz.html
http://www.yqcq.gov.cn/e/space/?userid=652926&yqcq.xml?feed_filter=20160916If6Sq.html
http://www.yqcq.gov.cn/e/space/?userid=652928&yqcq.xml?feed_filter=20160916Ry7Cd.html
http://www.yqcq.gov.cn/e/space/?userid=652929&yqcq.xml?feed_filter=20160916Ha4Rg.html
http://www.yqcq.gov.cn/e/space/?userid=652932&yqcq.xml?feed_filter=20160916Do4Lu.html
http://www.yqcq.gov.cn/e/space/?userid=652934&yqcq.xml?feed_filter=20160916Aw6Gb.html
http://www.yqcq.gov.cn/e/space/?userid=652936&yqcq.xml?feed_filter=20160916Xu3Gu.html
http://www.yqcq.gov.cn/e/space/?userid=652939&yqcq.xml?feed_filter=20160916Cm5Fx.html
http://www.yqcq.gov.cn/e/space/?userid=652941&yqcq.xml?feed_filter=20160916Ys1Pd.html
http://www.yqcq.gov.cn/e/space/?userid=652943&yqcq.xml?feed_filter=20160916Yh2Wi.html
http://www.yqcq.gov.cn/e/space/?userid=652946&yqcq.xml?feed_filter=20160916Ed8Yu.html
http://www.yqcq.gov.cn/e/space/?userid=652947&yqcq.xml?feed_filter=20160916De9Fr.html
http://www.yqcq.gov.cn/e/space/?userid=652948&yqcq.xml?feed_filter=20160916Ix4Qz.html
http://www.yqcq.gov.cn/e/space/?userid=652951&yqcq.xml?feed_filter=20160916Xi5Vj.html
http://www.yqcq.gov.cn/e/space/?userid=652953&yqcq.xml?feed_filter=20160916Ii4Zv.html
http://www.yqcq.gov.cn/e/space/?userid=652955&yqcq.xml?feed_filter=20160916As1Iq.html
http://www.yqcq.gov.cn/e/space/?userid=652957&yqcq.xml?feed_filter=20160916Ia7Gm.html
http://www.yqcq.gov.cn/e/space/?userid=652959&yqcq.xml?feed_filter=20160916Gi7Vc.html
http://www.yqcq.gov.cn/e/space/?userid=652961&yqcq.xml?feed_filter=20160916Bh1Oe.html
http://www.yqcq.gov.cn/e/space/?userid=652964&yqcq.xml?feed_filter=20160916En8Zk.html
http://www.yqcq.gov.cn/e/space/?userid=652965&yqcq.xml?feed_filter=20160916Hg9Po.html
http://www.yqcq.gov.cn/e/space/?userid=652967&yqcq.xml?feed_filter=20160916Uu8Cm.html
http://www.yqcq.gov.cn/e/space/?userid=652969&yqcq.xml?feed_filter=20160916Xa6Dm.html
http://www.yqcq.gov.cn/e/space/?userid=652970&yqcq.xml?feed_filter=20160916Ew2Mc.html
http://www.yqcq.gov.cn/e/space/?userid=652973&yqcq.xml?feed_filter=20160916Xm0Uj.html
http://www.yqcq.gov.cn/e/space/?userid=652975&yqcq.xml?feed_filter=20160916Ms3Rr.html
http://www.yqcq.gov.cn/e/space/?userid=652977&yqcq.xml?feed_filter=20160916Zm4Yz.html
http://www.yqcq.gov.cn/e/space/?userid=652980&yqcq.xml?feed_filter=20160916Sv7Hh.html
http://www.yqcq.gov.cn/e/space/?userid=652983&yqcq.xml?feed_filter=20160916Yz3Og.html
http://www.yqcq.gov.cn/e/space/?userid=652984&yqcq.xml?feed_filter=20160916Xg2Nu.html
http://www.yqcq.gov.cn/e/space/?userid=652986&yqcq.xml?feed_filter=20160916Ki9Ut.html
http://www.yqcq.gov.cn/e/space/?userid=652988&yqcq.xml?feed_filter=20160916Mr7Tj.html
http://www.yqcq.gov.cn/e/space/?userid=652989&yqcq.xml?feed_filter=20160916Jw8Hq.html
http://www.yqcq.gov.cn/e/space/?userid=652991&yqcq.xml?feed_filter=20160916Id9Xo.html
http://www.yqcq.gov.cn/e/space/?userid=652993&yqcq.xml?feed_filter=20160916Hc7Fr.html
http://www.yqcq.gov.cn/e/space/?userid=652995&yqcq.xml?feed_filter=20160916Dd3Zq.html
http://www.yqcq.gov.cn/e/space/?userid=652998&yqcq.xml?feed_filter=20160916Zm4Ld.html
http://www.yqcq.gov.cn/e/space/?userid=653001&yqcq.xml?feed_filter=20160916He6Dr.html
http://www.yqcq.gov.cn/e/space/?userid=653002&yqcq.xml?feed_filter=20160916Cf5Jc.html
http://www.yqcq.gov.cn/e/space/?userid=653005&yqcq.xml?feed_filter=20160916Pd2Hn.html
http://www.yqcq.gov.cn/e/space/?userid=653007&yqcq.xml?feed_filter=20160916Af6Oq.html
http://www.yqcq.gov.cn/e/space/?userid=653008&yqcq.xml?feed_filter=20160916Tr5Nr.html
http://www.yqcq.gov.cn/e/space/?userid=653009&yqcq.xml?feed_filter=20160916Pv4Wg.html
http://www.yqcq.gov.cn/e/space/?userid=653011&yqcq.xml?feed_filter=20160916Jl2Tx.html
http://www.yqcq.gov.cn/e/space/?userid=653012&yqcq.xml?feed_filter=20160916It9Eh.html
http://www.yqcq.gov.cn/e/space/?userid=653017&yqcq.xml?feed_filter=20160916Om6Ro.html
http://www.yqcq.gov.cn/e/space/?userid=653019&yqcq.xml?feed_filter=20160916Hs0Sn.html
http://www.yqcq.gov.cn/e/space/?userid=653020&yqcq.xml?feed_filter=20160916Gi6Ug.html
http://www.yqcq.gov.cn/e/space/?userid=653022&yqcq.xml?feed_filter=20160916Wf0Xs.html
http://www.yqcq.gov.cn/e/space/?userid=653024&yqcq.xml?feed_filter=20160916Sa4Qv.html
http://www.yqcq.gov.cn/e/space/?userid=653026&yqcq.xml?feed_filter=20160916Oc3Fm.html
http://www.yqcq.gov.cn/e/space/?userid=653028&yqcq.xml?feed_filter=20160916Km2Lu.html
http://www.yqcq.gov.cn/e/space/?userid=653031&yqcq.xml?feed_filter=20160916Jf6Kv.html
http://www.yqcq.gov.cn/e/space/?userid=653032&yqcq.xml?feed_filter=20160916Ka8Hn.html
http://www.yqcq.gov.cn/e/space/?userid=653035&yqcq.xml?feed_filter=20160916Zh0Ml.html
http://www.yqcq.gov.cn/e/space/?userid=653037&yqcq.xml?feed_filter=20160916Rx2Ai.html
http://www.yqcq.gov.cn/e/space/?userid=653039&yqcq.xml?feed_filter=20160916Vg1Va.html
http://www.yqcq.gov.cn/e/space/?userid=653043&yqcq.xml?feed_filter=20160916Po4Ad.html
http://www.yqcq.gov.cn/e/space/?userid=653046&yqcq.xml?feed_filter=20160916Wf0Tt.html
http://www.yqcq.gov.cn/e/space/?userid=653048&yqcq.xml?feed_filter=20160916Oj2Rt.html
http://www.yqcq.gov.cn/e/space/?userid=653050&yqcq.xml?feed_filter=20160916Sp2Wj.html
http://www.yqcq.gov.cn/e/space/?userid=653053&yqcq.xml?feed_filter=20160916Ll0Kh.html
http://www.yqcq.gov.cn/e/space/?userid=653056&yqcq.xml?feed_filter=20160916Dp3Dr.html
http://www.yqcq.gov.cn/e/space/?userid=653057&yqcq.xml?feed_filter=20160916Ya4Td.html
http://www.yqcq.gov.cn/e/space/?userid=653060&yqcq.xml?feed_filter=20160916Hs4Sh.html
http://www.yqcq.gov.cn/e/space/?userid=653062&yqcq.xml?feed_filter=20160916Rr1Ux.html
http://www.yqcq.gov.cn/e/space/?userid=653063&yqcq.xml?feed_filter=20160916Mh6Fc.html
http://www.yqcq.gov.cn/e/space/?userid=653065&yqcq.xml?feed_filter=20160916Na6Rc.html
http://www.yqcq.gov.cn/e/space/?userid=653066&yqcq.xml?feed_filter=20160916Jx3Sk.html
http://www.yqcq.gov.cn/e/space/?userid=653067&yqcq.xml?feed_filter=20160916Rc0Ky.html
http://www.yqcq.gov.cn/e/space/?userid=653069&yqcq.xml?feed_filter=20160916Tz7Tv.html
http://www.yqcq.gov.cn/e/space/?userid=653071&yqcq.xml?feed_filter=20160916Xq9Bt.html
http://www.yqcq.gov.cn/e/space/?userid=653073&yqcq.xml?feed_filter=20160916Wz5Ae.html
http://www.yqcq.gov.cn/e/space/?userid=653076&yqcq.xml?feed_filter=20160916Xb5Yg.html
http://www.yqcq.gov.cn/e/space/?userid=653080&yqcq.xml?feed_filter=20160916Si2Rj.html
http://www.yqcq.gov.cn/e/space/?userid=653082&yqcq.xml?feed_filter=20160916Xg1Tr.html
http://www.yqcq.gov.cn/e/space/?userid=653084&yqcq.xml?feed_filter=20160916Zx6Iy.html
http://www.yqcq.gov.cn/e/space/?userid=653085&yqcq.xml?feed_filter=20160916Dt2Iw.html
http://www.yqcq.gov.cn/e/space/?userid=653088&yqcq.xml?feed_filter=20160916Ep6Ct.html
http://www.yqcq.gov.cn/e/space/?userid=653091&yqcq.xml?feed_filter=20160916Zv4Sg.html
http://www.yqcq.gov.cn/e/space/?userid=653092&yqcq.xml?feed_filter=20160916Ol1Vv.html
http://www.yqcq.gov.cn/e/space/?userid=653095&yqcq.xml?feed_filter=20160916Ru2Zp.html
http://www.yqcq.gov.cn/e/space/?userid=653098&yqcq.xml?feed_filter=20160916Ns0Pn.html
http://www.yqcq.gov.cn/e/space/?userid=653100&yqcq.xml?feed_filter=20160916Sb5Td.html
http://www.yqcq.gov.cn/e/space/?userid=653102&yqcq.xml?feed_filter=20160916Vx9El.html
http://www.yqcq.gov.cn/e/space/?userid=653104&yqcq.xml?feed_filter=20160916Bk5Sd.html
http://www.yqcq.gov.cn/e/space/?userid=653105&yqcq.xml?feed_filter=20160916Ac8Gl.html
http://www.yqcq.gov.cn/e/space/?userid=653106&yqcq.xml?feed_filter=20160916Ny7Ma.html
http://www.yqcq.gov.cn/e/space/?userid=653109&yqcq.xml?feed_filter=20160916Ru1Fh.html
http://www.yqcq.gov.cn/e/space/?userid=653111&yqcq.xml?feed_filter=20160916Gg8Hy.html
http://www.yqcq.gov.cn/e/space/?userid=653114&yqcq.xml?feed_filter=20160916Qn4Ri.html
http://www.yqcq.gov.cn/e/space/?userid=653117&yqcq.xml?feed_filter=20160916No6Rf.html
http://www.yqcq.gov.cn/e/space/?userid=653118&yqcq.xml?feed_filter=20160916Hi7Zq.html
http://www.yqcq.gov.cn/e/space/?userid=653120&yqcq.xml?feed_filter=20160916Uv8Pc.html
http://www.yqcq.gov.cn/e/space/?userid=653123&yqcq.xml?feed_filter=20160916Pd1Yr.html
http://www.yqcq.gov.cn/e/space/?userid=653124&yqcq.xml?feed_filter=20160916Bt7Bl.html
http://www.yqcq.gov.cn/e/space/?userid=653127&yqcq.xml?feed_filter=20160916Fk1Yy.html
http://www.yqcq.gov.cn/e/space/?userid=653129&yqcq.xml?feed_filter=20160916Hl9Zc.html
http://www.yqcq.gov.cn/e/space/?userid=653132&yqcq.xml?feed_filter=20160916Hd4Aw.html
http://www.yqcq.gov.cn/e/space/?userid=653134&yqcq.xml?feed_filter=20160916Uj2Aj.html
http://www.yqcq.gov.cn/e/space/?userid=653138&yqcq.xml?feed_filter=20160916Hx0Mn.html
http://www.yqcq.gov.cn/e/space/?userid=653139&yqcq.xml?feed_filter=20160916Qi3Jx.html
http://www.yqcq.gov.cn/e/space/?userid=653142&yqcq.xml?feed_filter=20160916Oo3Il.html
http://www.yqcq.gov.cn/e/space/?userid=653144&yqcq.xml?feed_filter=20160916Rh5Ph.html
http://www.yqcq.gov.cn/e/space/?userid=653147&yqcq.xml?feed_filter=20160916Mq8Cn.html
http://www.yqcq.gov.cn/e/space/?userid=653149&yqcq.xml?feed_filter=20160916Ud5Db.html
http://www.yqcq.gov.cn/e/space/?userid=653151&yqcq.xml?feed_filter=20160916Vp4Df.html
http://www.yqcq.gov.cn/e/space/?userid=653154&yqcq.xml?feed_filter=20160916Kp6Np.html
http://www.yqcq.gov.cn/e/space/?userid=653155&yqcq.xml?feed_filter=20160916Xq4Dx.html
http://www.yqcq.gov.cn/e/space/?userid=653158&yqcq.xml?feed_filter=20160916Pj4Dp.html
http://www.yqcq.gov.cn/e/space/?userid=653161&yqcq.xml?feed_filter=20160916Pq8Lx.html
http://www.yqcq.gov.cn/e/space/?userid=653162&yqcq.xml?feed_filter=20160916Ho5Mq.html
http://www.yqcq.gov.cn/e/space/?userid=653164&yqcq.xml?feed_filter=20160916Cq8Uu.html
http://www.yqcq.gov.cn/e/space/?userid=653166&yqcq.xml?feed_filter=20160916Ci2Mq.html
http://www.yqcq.gov.cn/e/space/?userid=653167&yqcq.xml?feed_filter=20160916Gx4Qb.html
http://www.yqcq.gov.cn/e/space/?userid=653169&yqcq.xml?feed_filter=20160916Bg8Oj.html
http://www.yqcq.gov.cn/e/space/?userid=653173&yqcq.xml?feed_filter=20160916Zh2Im.html
http://www.yqcq.gov.cn/e/space/?userid=653174&yqcq.xml?feed_filter=20160916Rg1Ro.html
http://www.yqcq.gov.cn/e/space/?userid=653176&yqcq.xml?feed_filter=20160916Rc6Bt.html
http://www.yqcq.gov.cn/e/space/?userid=653177&yqcq.xml?feed_filter=20160916Hh0Mn.html
http://www.yqcq.gov.cn/e/space/?userid=653180&yqcq.xml?feed_filter=20160916Lj0Km.html
http://www.yqcq.gov.cn/e/space/?userid=653183&yqcq.xml?feed_filter=20160916Cc6Uv.html
http://www.yqcq.gov.cn/e/space/?userid=653184&yqcq.xml?feed_filter=20160916Xm6Ae.html
http://www.yqcq.gov.cn/e/space/?userid=653187&yqcq.xml?feed_filter=20160916Jl5Hr.html
http://www.yqcq.gov.cn/e/space/?userid=653189&yqcq.xml?feed_filter=20160916Zw8Fi.html
http://www.yqcq.gov.cn/e/space/?userid=653192&yqcq.xml?feed_filter=20160916Fl5Kw.html
http://www.yqcq.gov.cn/e/space/?userid=653194&yqcq.xml?feed_filter=20160916Us4Ya.html
http://www.yqcq.gov.cn/e/space/?userid=653195&yqcq.xml?feed_filter=20160916Xg7Ja.html
http://www.yqcq.gov.cn/e/space/?userid=653198&yqcq.xml?feed_filter=20160916Df0Jg.html
http://www.yqcq.gov.cn/e/space/?userid=653199&yqcq.xml?feed_filter=20160916Ov3Vt.html
http://www.yqcq.gov.cn/e/space/?userid=653202&yqcq.xml?feed_filter=20160916Aa4Kg.html
http://www.yqcq.gov.cn/e/space/?userid=653203&yqcq.xml?feed_filter=20160916Im3Kr.html
http://www.yqcq.gov.cn/e/space/?userid=653206&yqcq.xml?feed_filter=20160916Lk5Vn.html
http://www.yqcq.gov.cn/e/space/?userid=653208&yqcq.xml?feed_filter=20160916Lw1Jo.html
http://www.yqcq.gov.cn/e/space/?userid=653210&yqcq.xml?feed_filter=20160916Nu6Mf.html
http://www.yqcq.gov.cn/e/space/?userid=653212&yqcq.xml?feed_filter=20160916Ec4Ne.html
http://www.yqcq.gov.cn/e/space/?userid=653215&yqcq.xml?feed_filter=20160916Mg5Ly.html
http://www.yqcq.gov.cn/e/space/?userid=653217&yqcq.xml?feed_filter=20160916Tf3Kd.html
http://www.yqcq.gov.cn/e/space/?userid=653219&yqcq.xml?feed_filter=20160916Ip8Ut.html
http://www.yqcq.gov.cn/e/space/?userid=653223&yqcq.xml?feed_filter=20160916Yu8Bs.html
http://www.yqcq.gov.cn/e/space/?userid=653225&yqcq.xml?feed_filter=20160916Ts1Fm.html
http://www.yqcq.gov.cn/e/space/?userid=653228&yqcq.xml?feed_filter=20160916Sj9Sc.html
http://www.yqcq.gov.cn/e/space/?userid=653231&yqcq.xml?feed_filter=20160916Yu3Dy.html
http://www.yqcq.gov.cn/e/space/?userid=653233&yqcq.xml?feed_filter=20160916Df8Jt.html
http://www.yqcq.gov.cn/e/space/?userid=653236&yqcq.xml?feed_filter=20160916Mw4Sp.html
http://www.yqcq.gov.cn/e/space/?userid=653238&yqcq.xml?feed_filter=20160916Yq1Vr.html
http://www.yqcq.gov.cn/e/space/?userid=653241&yqcq.xml?feed_filter=20160916Tx2Rj.html
http://www.yqcq.gov.cn/e/space/?userid=653244&yqcq.xml?feed_filter=20160916Vc0Yn.html
http://www.yqcq.gov.cn/e/space/?userid=653245&yqcq.xml?feed_filter=20160916Na2Xx.html
http://www.yqcq.gov.cn/e/space/?userid=653249&yqcq.xml?feed_filter=20160916Ao3Wv.html
http://www.yqcq.gov.cn/e/space/?userid=653251&yqcq.xml?feed_filter=20160916Ij7Gb.html
http://www.yqcq.gov.cn/e/space/?userid=653254&yqcq.xml?feed_filter=20160916Qr6Jd.html
http://www.yqcq.gov.cn/e/space/?userid=653257&yqcq.xml?feed_filter=20160916Db9Yo.html
http://www.yqcq.gov.cn/e/space/?userid=653259&yqcq.xml?feed_filter=20160916Fm7Xu.html
http://www.yqcq.gov.cn/e/space/?userid=653261&yqcq.xml?feed_filter=20160916Ai7Mw.html
http://www.yqcq.gov.cn/e/space/?userid=653263&yqcq.xml?feed_filter=20160916Rs6Ne.html
http://www.yqcq.gov.cn/e/space/?userid=653264&yqcq.xml?feed_filter=20160916Lw5Fn.html
http://www.yqcq.gov.cn/e/space/?userid=653265&yqcq.xml?feed_filter=20160916Jx1Nf.html
http://www.yqcq.gov.cn/e/space/?userid=653267&yqcq.xml?feed_filter=20160916Jo0Je.html
http://www.yqcq.gov.cn/e/space/?userid=653268&yqcq.xml?feed_filter=20160916Dd6Yk.html
http://www.yqcq.gov.cn/e/space/?userid=653270&yqcq.xml?feed_filter=20160916Cx3Xh.html
http://www.yqcq.gov.cn/e/space/?userid=653273&yqcq.xml?feed_filter=20160916Vd4Sp.html
http://www.yqcq.gov.cn/e/space/?userid=653274&yqcq.xml?feed_filter=20160916Jh2Xy.html
http://www.yqcq.gov.cn/e/space/?userid=653276&yqcq.xml?feed_filter=20160916Cb8Et.html
http://www.yqcq.gov.cn/e/space/?userid=653277&yqcq.xml?feed_filter=20160916Le8Zc.html
http://www.yqcq.gov.cn/e/space/?userid=653280&yqcq.xml?feed_filter=20160916Js1Ug.html
http://www.yqcq.gov.cn/e/space/?userid=653282&yqcq.xml?feed_filter=20160916Zd6Vd.html
http://www.yqcq.gov.cn/e/space/?userid=653283&yqcq.xml?feed_filter=20160916Ej3Mq.html
http://www.yqcq.gov.cn/e/space/?userid=653285&yqcq.xml?feed_filter=20160916Hu9Zv.html
http://www.yqcq.gov.cn/e/space/?userid=653286&yqcq.xml?feed_filter=20160916Bh0Tk.html
http://www.yqcq.gov.cn/e/space/?userid=653288&yqcq.xml?feed_filter=20160916Vk7Tr.html
http://www.yqcq.gov.cn/e/space/?userid=653290&yqcq.xml?feed_filter=20160916Un9Bi.html
http://www.yqcq.gov.cn/e/space/?userid=653292&yqcq.xml?feed_filter=20160916Pr0Ya.html
http://www.yqcq.gov.cn/e/space/?userid=653295&yqcq.xml?feed_filter=20160916Bt9Lk.html
http://www.yqcq.gov.cn/e/space/?userid=653296&yqcq.xml?feed_filter=20160916Vl5Cg.html
http://www.yqcq.gov.cn/e/space/?userid=653299&yqcq.xml?feed_filter=20160916Uc6Lf.html
http://www.yqcq.gov.cn/e/space/?userid=653302&yqcq.xml?feed_filter=20160916Bc5Qf.html
http://www.yqcq.gov.cn/e/space/?userid=653304&yqcq.xml?feed_filter=20160916Zb3Ii.html
http://www.yqcq.gov.cn/e/space/?userid=653306&yqcq.xml?feed_filter=20160916Bu4Ld.html
http://www.yqcq.gov.cn/e/space/?userid=653309&yqcq.xml?feed_filter=20160916Iv1Ex.html
http://www.yqcq.gov.cn/e/space/?userid=653311&yqcq.xml?feed_filter=20160916Le3Ds.html
http://www.yqcq.gov.cn/e/space/?userid=653313&yqcq.xml?feed_filter=20160916Ja2Pq.html
http://www.yqcq.gov.cn/e/space/?userid=653314&yqcq.xml?feed_filter=20160916Hv9Oq.html
http://www.yqcq.gov.cn/e/space/?userid=653316&yqcq.xml?feed_filter=20160916Ii9Nf.html
http://www.yqcq.gov.cn/e/space/?userid=653317&yqcq.xml?feed_filter=20160916Cu8Gp.html
http://www.yqcq.gov.cn/e/space/?userid=653319&yqcq.xml?feed_filter=20160916Wb1Ge.html
http://www.yqcq.gov.cn/e/space/?userid=653320&yqcq.xml?feed_filter=20160916Rd5Rk.html
http://www.yqcq.gov.cn/e/space/?userid=653322&yqcq.xml?feed_filter=20160916Cr6Ji.html
http://www.yqcq.gov.cn/e/space/?userid=653324&yqcq.xml?feed_filter=20160916Bh9Sw.html
http://www.yqcq.gov.cn/e/space/?userid=653325&yqcq.xml?feed_filter=20160916Qh9Ym.html
http://www.yqcq.gov.cn/e/space/?userid=653326&yqcq.xml?feed_filter=20160916It0Zk.html
http://www.yqcq.gov.cn/e/space/?userid=653328&yqcq.xml?feed_filter=20160916Ac3Wa.html
http://www.yqcq.gov.cn/e/space/?userid=653330&yqcq.xml?feed_filter=20160916Is6Qi.html
http://www.yqcq.gov.cn/e/space/?userid=653332&yqcq.xml?feed_filter=20160916Rk0Hw.html
http://www.yqcq.gov.cn/e/space/?userid=653334&yqcq.xml?feed_filter=20160916In2Yn.html
http://www.yqcq.gov.cn/e/space/?userid=653335&yqcq.xml?feed_filter=20160916Tk8Qg.html
http://www.yqcq.gov.cn/e/space/?userid=653338&yqcq.xml?feed_filter=20160916Su1Jx.html
http://www.yqcq.gov.cn/e/space/?userid=653341&yqcq.xml?feed_filter=20160916Ew4Xh.html
http://www.yqcq.gov.cn/e/space/?userid=653342&yqcq.xml?feed_filter=20160916Ow2Le.html
http://www.yqcq.gov.cn/e/space/?userid=653344&yqcq.xml?feed_filter=20160916Ym3Os.html
http://www.yqcq.gov.cn/e/space/?userid=653347&yqcq.xml?feed_filter=20160916Df6Mt.html
http://www.yqcq.gov.cn/e/space/?userid=653349&yqcq.xml?feed_filter=20160916Uc6Wx.html
http://www.yqcq.gov.cn/e/space/?userid=653351&yqcq.xml?feed_filter=20160916Ay7Zg.html
http://www.yqcq.gov.cn/e/space/?userid=653354&yqcq.xml?feed_filter=20160916Pv4Vk.html
http://www.yqcq.gov.cn/e/space/?userid=653356&yqcq.xml?feed_filter=20160916Jr9Gf.html
http://www.yqcq.gov.cn/e/space/?userid=653359&yqcq.xml?feed_filter=20160916Zn5Ql.html
http://www.yqcq.gov.cn/e/space/?userid=653361&yqcq.xml?feed_filter=20160916Qf5Jm.html
http://www.yqcq.gov.cn/e/space/?userid=653363&yqcq.xml?feed_filter=20160916Af5Zb.html
http://www.yqcq.gov.cn/e/space/?userid=653364&yqcq.xml?feed_filter=20160916Lp4Xs.html
http://www.yqcq.gov.cn/e/space/?userid=653367&yqcq.xml?feed_filter=20160916Mf7Ja.html
http://www.yqcq.gov.cn/e/space/?userid=653369&yqcq.xml?feed_filter=20160916Cf2Ei.html
http://www.yqcq.gov.cn/e/space/?userid=653372&yqcq.xml?feed_filter=20160916Gw2Yg.html
http://www.yqcq.gov.cn/e/space/?userid=653375&yqcq.xml?feed_filter=20160916Cr8Co.html
http://www.yqcq.gov.cn/e/space/?userid=653376&yqcq.xml?feed_filter=20160916Jz0Wa.html
http://www.yqcq.gov.cn/e/space/?userid=653379&yqcq.xml?feed_filter=20160916Go3Ny.html
http://www.yqcq.gov.cn/e/space/?userid=653382&yqcq.xml?feed_filter=20160916Xz8Pb.html
http://www.yqcq.gov.cn/e/space/?userid=653383&yqcq.xml?feed_filter=20160916Yi7Ro.html
http://www.yqcq.gov.cn/e/space/?userid=653387&yqcq.xml?feed_filter=20160916Sd1Fx.html
http://www.yqcq.gov.cn/e/space/?userid=653389&yqcq.xml?feed_filter=20160916Mg9Jd.html
http://www.yqcq.gov.cn/e/space/?userid=653391&yqcq.xml?feed_filter=20160916Kq9Du.html
http://www.yqcq.gov.cn/e/space/?userid=653394&yqcq.xml?feed_filter=20160916Lf8Yr.html
http://www.yqcq.gov.cn/e/space/?userid=653396&yqcq.xml?feed_filter=20160916Qf7Yj.html
http://www.yqcq.gov.cn/e/space/?userid=653397&yqcq.xml?feed_filter=20160916Jg4Aa.html
http://www.yqcq.gov.cn/e/space/?userid=653399&yqcq.xml?feed_filter=20160916Qm7Ue.html
http://www.yqcq.gov.cn/e/space/?userid=653401&yqcq.xml?feed_filter=20160916Gk2Ej.html
http://www.yqcq.gov.cn/e/space/?userid=653404&yqcq.xml?feed_filter=20160916Wo2Ez.html
http://www.yqcq.gov.cn/e/space/?userid=653406&yqcq.xml?feed_filter=20160916Fm3Et.html
http://www.yqcq.gov.cn/e/space/?userid=653408&yqcq.xml?feed_filter=20160916Rn1Ue.html
http://www.yqcq.gov.cn/e/space/?userid=653410&yqcq.xml?feed_filter=20160916Mp1Qg.html
http://www.yqcq.gov.cn/e/space/?userid=653411&yqcq.xml?feed_filter=20160916Vr8Ki.html
http://www.yqcq.gov.cn/e/space/?userid=653414&yqcq.xml?feed_filter=20160916Hq6Gc.html
http://www.yqcq.gov.cn/e/space/?userid=653416&yqcq.xml?feed_filter=20160916Dt2Ac.html
http://www.yqcq.gov.cn/e/space/?userid=653419&yqcq.xml?feed_filter=20160916Bx7Wm.html
http://www.yqcq.gov.cn/e/space/?userid=653421&yqcq.xml?feed_filter=20160916Xw0Aq.html
http://www.yqcq.gov.cn/e/space/?userid=653424&yqcq.xml?feed_filter=20160916Yz9Ug.html
http://www.yqcq.gov.cn/e/space/?userid=653428&yqcq.xml?feed_filter=20160916Ty6Ja.html
http://www.yqcq.gov.cn/e/space/?userid=653430&yqcq.xml?feed_filter=20160916Lp8Fk.html
http://www.yqcq.gov.cn/e/space/?userid=653432&yqcq.xml?feed_filter=20160916Wr6Hg.html
http://www.yqcq.gov.cn/e/space/?userid=653434&yqcq.xml?feed_filter=20160916Ae5Hy.html
http://www.yqcq.gov.cn/e/space/?userid=653436&yqcq.xml?feed_filter=20160916Cg8Jq.html
http://www.yqcq.gov.cn/e/space/?userid=653439&yqcq.xml?feed_filter=20160916Zv9Db.html
http://www.yqcq.gov.cn/e/space/?userid=653440&yqcq.xml?feed_filter=20160916Kd1Or.html
http://www.yqcq.gov.cn/e/space/?userid=653444&yqcq.xml?feed_filter=20160916Xt7Ii.html
http://www.yqcq.gov.cn/e/space/?userid=653445&yqcq.xml?feed_filter=20160916Gn3Oe.html
http://www.yqcq.gov.cn/e/space/?userid=653446&yqcq.xml?feed_filter=20160916Kx7Kv.html
http://www.yqcq.gov.cn/e/space/?userid=653448&yqcq.xml?feed_filter=20160916Kj6Rf.html
http://www.yqcq.gov.cn/e/space/?userid=653450&yqcq.xml?feed_filter=20160916Vn7Po.html
http://www.yqcq.gov.cn/e/space/?userid=653451&yqcq.xml?feed_filter=20160916Dy2Fc.html
http://www.yqcq.gov.cn/e/space/?userid=653452&yqcq.xml?feed_filter=20160916Ay5Ld.html
http://www.yqcq.gov.cn/e/space/?userid=653454&yqcq.xml?feed_filter=20160916Dj2Ks.html
http://www.yqcq.gov.cn/e/space/?userid=653456&yqcq.xml?feed_filter=20160916Vo3Cl.html
http://www.yqcq.gov.cn/e/space/?userid=653457&yqcq.xml?feed_filter=20160916Er4Ny.html
http://www.yqcq.gov.cn/e/space/?userid=653459&yqcq.xml?feed_filter=20160916Hw1Rp.html
http://www.yqcq.gov.cn/e/space/?userid=653460&yqcq.xml?feed_filter=20160916Lr2Hx.html
http://www.yqcq.gov.cn/e/space/?userid=653462&yqcq.xml?feed_filter=20160916Ua2Gj.html
http://www.yqcq.gov.cn/e/space/?userid=653463&yqcq.xml?feed_filter=20160916Xp2Sx.html
http://www.yqcq.gov.cn/e/space/?userid=653466&yqcq.xml?feed_filter=20160916Eg1Wb.html
http://www.yqcq.gov.cn/e/space/?userid=653467&yqcq.xml?feed_filter=20160916Jq1To.html
http://www.yqcq.gov.cn/e/space/?userid=653470&yqcq.xml?feed_filter=20160916Ac3Xp.html
http://www.yqcq.gov.cn/e/space/?userid=653473&yqcq.xml?feed_filter=20160916Nc0Qm.html
http://www.yqcq.gov.cn/e/space/?userid=653475&yqcq.xml?feed_filter=20160916Uh0Cn.html
http://www.yqcq.gov.cn/e/space/?userid=653478&yqcq.xml?feed_filter=20160916Zt6Ht.html
http://www.yqcq.gov.cn/e/space/?userid=653480&yqcq.xml?feed_filter=20160916Mv4Pe.html
http://www.yqcq.gov.cn/e/space/?userid=653483&yqcq.xml?feed_filter=20160916Dw3Ov.html
http://www.yqcq.gov.cn/e/space/?userid=653486&yqcq.xml?feed_filter=20160916Bm4Mz.html
http://www.yqcq.gov.cn/e/space/?userid=653489&yqcq.xml?feed_filter=20160916Ji3Zq.html
http://www.yqcq.gov.cn/e/space/?userid=653491&yqcq.xml?feed_filter=20160916Vc5Gg.html
http://www.yqcq.gov.cn/e/space/?userid=653493&yqcq.xml?feed_filter=20160916Wp7Rv.html
http://www.yqcq.gov.cn/e/space/?userid=653494&yqcq.xml?feed_filter=20160916Vu0Lf.html
http://www.yqcq.gov.cn/e/space/?userid=653495&yqcq.xml?feed_filter=20160916Qf2Kn.html
http://www.yqcq.gov.cn/e/space/?userid=653497&yqcq.xml?feed_filter=20160916Pp3Ep.html
http://www.yqcq.gov.cn/e/space/?userid=653499&yqcq.xml?feed_filter=20160916Jn5Fo.html
http://www.yqcq.gov.cn/e/space/?userid=653501&yqcq.xml?feed_filter=20160916Ja2Cy.html
http://www.yqcq.gov.cn/e/space/?userid=653503&yqcq.xml?feed_filter=20160916Nd6Xy.html
http://www.yqcq.gov.cn/e/space/?userid=653506&yqcq.xml?feed_filter=20160916Eo7Tu.html
http://www.yqcq.gov.cn/e/space/?userid=653509&yqcq.xml?feed_filter=20160916Hc1Si.html
http://www.yqcq.gov.cn/e/space/?userid=653512&yqcq.xml?feed_filter=20160916Uv8Lu.html
http://www.yqcq.gov.cn/e/space/?userid=653514&yqcq.xml?feed_filter=20160916Lf8Sg.html
http://www.yqcq.gov.cn/e/space/?userid=653516&yqcq.xml?feed_filter=20160916Lr3Am.html
http://www.yqcq.gov.cn/e/space/?userid=653518&yqcq.xml?feed_filter=20160916Zx1Tw.html
http://www.yqcq.gov.cn/e/space/?userid=653521&yqcq.xml?feed_filter=20160916Sp2Ap.html
http://www.yqcq.gov.cn/e/space/?userid=653524&yqcq.xml?feed_filter=20160916Ul8Fp.html
http://www.yqcq.gov.cn/e/space/?userid=653528&yqcq.xml?feed_filter=20160916Sn3Pp.html
http://www.yqcq.gov.cn/e/space/?userid=653529&yqcq.xml?feed_filter=20160916Ts0Md.html
http://www.yqcq.gov.cn/e/space/?userid=653532&yqcq.xml?feed_filter=20160916Ps2Va.html
http://www.yqcq.gov.cn/e/space/?userid=653534&yqcq.xml?feed_filter=20160916Aj0Ya.html
http://www.yqcq.gov.cn/e/space/?userid=653535&yqcq.xml?feed_filter=20160916Pv4Xv.html
http://www.yqcq.gov.cn/e/space/?userid=653538&yqcq.xml?feed_filter=20160916Pc3Gv.html
http://www.yqcq.gov.cn/e/space/?userid=653540&yqcq.xml?feed_filter=20160916Cx0Lm.html
http://www.yqcq.gov.cn/e/space/?userid=653544&yqcq.xml?feed_filter=20160916Li5Ii.html
http://www.yqcq.gov.cn/e/space/?userid=653545&yqcq.xml?feed_filter=20160916Mt3Nt.html
http://www.yqcq.gov.cn/e/space/?userid=653548&yqcq.xml?feed_filter=20160916Oe3Eo.html
http://www.yqcq.gov.cn/e/space/?userid=653550&yqcq.xml?feed_filter=20160916Qe7Lp.html
http://www.yqcq.gov.cn/e/space/?userid=653553&yqcq.xml?feed_filter=20160916Id5Of.html
http://www.yqcq.gov.cn/e/space/?userid=653555&yqcq.xml?feed_filter=20160916Vb1Fk.html
http://www.yqcq.gov.cn/e/space/?userid=653557&yqcq.xml?feed_filter=20160916Wm4Ed.html
http://www.yqcq.gov.cn/e/space/?userid=653560&yqcq.xml?feed_filter=20160916Vi5Bg.html
http://www.yqcq.gov.cn/e/space/?userid=653561&yqcq.xml?feed_filter=20160916Ou5Sv.html
http://www.yqcq.gov.cn/e/space/?userid=653564&yqcq.xml?feed_filter=20160916Cy3Pq.html
http://www.yqcq.gov.cn/e/space/?userid=653566&yqcq.xml?feed_filter=20160916Au4Kt.html
http://www.yqcq.gov.cn/e/space/?userid=653569&yqcq.xml?feed_filter=20160916Di3Ph.html
http://www.yqcq.gov.cn/e/space/?userid=653570&yqcq.xml?feed_filter=20160916Jd2Zx.html
http://www.yqcq.gov.cn/e/space/?userid=653573&yqcq.xml?feed_filter=20160916Kd2Kf.html
http://www.yqcq.gov.cn/e/space/?userid=653575&yqcq.xml?feed_filter=20160916Na3Fw.html
http://www.yqcq.gov.cn/e/space/?userid=653578&yqcq.xml?feed_filter=20160916Xg2Iy.html
http://www.yqcq.gov.cn/e/space/?userid=653581&yqcq.xml?feed_filter=20160916Cx4Tf.html
http://www.yqcq.gov.cn/e/space/?userid=653584&yqcq.xml?feed_filter=20160916Nm1Oa.html
http://www.yqcq.gov.cn/e/space/?userid=653587&yqcq.xml?feed_filter=20160916Lz0Sk.html
http://www.yqcq.gov.cn/e/space/?userid=653590&yqcq.xml?feed_filter=20160916Wc4Vv.html
http://www.yqcq.gov.cn/e/space/?userid=653593&yqcq.xml?feed_filter=20160916Df7Gd.html
http://www.yqcq.gov.cn/e/space/?userid=653594&yqcq.xml?feed_filter=20160916Ik2Nb.html
http://www.yqcq.gov.cn/e/space/?userid=653597&yqcq.xml?feed_filter=20160916Kw6Nu.html
http://www.yqcq.gov.cn/e/space/?userid=653598&yqcq.xml?feed_filter=20160916Qj9Qs.html
http://www.yqcq.gov.cn/e/space/?userid=653600&yqcq.xml?feed_filter=20160916Yj8Gx.html
http://www.yqcq.gov.cn/e/space/?userid=653603&yqcq.xml?feed_filter=20160916Lb2Xh.html
http://www.yqcq.gov.cn/e/space/?userid=653605&yqcq.xml?feed_filter=20160916Nl9Cp.html
http://www.yqcq.gov.cn/e/space/?userid=653606&yqcq.xml?feed_filter=20160916Ki7Mx.html
http://www.yqcq.gov.cn/e/space/?userid=653608&yqcq.xml?feed_filter=20160916Qp8Fb.html
http://www.yqcq.gov.cn/e/space/?userid=653610&yqcq.xml?feed_filter=20160916Mx1Sr.html
http://www.yqcq.gov.cn/e/space/?userid=653612&yqcq.xml?feed_filter=20160916Zj2Up.html
http://www.yqcq.gov.cn/e/space/?userid=653615&yqcq.xml?feed_filter=20160916At3Lx.html
http://www.yqcq.gov.cn/e/space/?userid=653617&yqcq.xml?feed_filter=20160916Og7Xf.html
http://www.yqcq.gov.cn/e/space/?userid=653620&yqcq.xml?feed_filter=20160916Nu3Yv.html
http://www.yqcq.gov.cn/e/space/?userid=653623&yqcq.xml?feed_filter=20160916Wz9St.html
http://www.yqcq.gov.cn/e/space/?userid=653627&yqcq.xml?feed_filter=20160916Aq2Hq.html
http://www.yqcq.gov.cn/e/space/?userid=653628&yqcq.xml?feed_filter=20160916Nd9Fi.html
http://www.yqcq.gov.cn/e/space/?userid=653631&yqcq.xml?feed_filter=20160916Is3At.html
http://www.yqcq.gov.cn/e/space/?userid=653634&yqcq.xml?feed_filter=20160916Cf6Eb.html
http://www.yqcq.gov.cn/e/space/?userid=653636&yqcq.xml?feed_filter=20160916Ru1Vp.html
http://www.yqcq.gov.cn/e/space/?userid=653639&yqcq.xml?feed_filter=20160916Vg5Vy.html
http://www.yqcq.gov.cn/e/space/?userid=653641&yqcq.xml?feed_filter=20160916Jh4Xj.html
http://www.yqcq.gov.cn/e/space/?userid=653643&yqcq.xml?feed_filter=20160916Mv6Yf.html
http://www.yqcq.gov.cn/e/space/?userid=653644&yqcq.xml?feed_filter=20160916Mt6Cs.html
http://www.yqcq.gov.cn/e/space/?userid=653646&yqcq.xml?feed_filter=20160916Al8Ss.html
http://www.yqcq.gov.cn/e/space/?userid=653648&yqcq.xml?feed_filter=20160916Lw8Xt.html
http://www.yqcq.gov.cn/e/space/?userid=653651&yqcq.xml?feed_filter=20160916Ft6Bo.html
http://www.yqcq.gov.cn/e/space/?userid=653652&yqcq.xml?feed_filter=20160916Hm9Wv.html
http://www.yqcq.gov.cn/e/space/?userid=653655&yqcq.xml?feed_filter=20160916Ct2Uv.html
http://www.yqcq.gov.cn/e/space/?userid=653656&yqcq.xml?feed_filter=20160916Qz9Kr.html
http://www.yqcq.gov.cn/e/space/?userid=653659&yqcq.xml?feed_filter=20160916Ru9Gt.html
http://www.yqcq.gov.cn/e/space/?userid=653661&yqcq.xml?feed_filter=20160916Iu3Xf.html
http://www.yqcq.gov.cn/e/space/?userid=653663&yqcq.xml?feed_filter=20160916Oz5Bh.html
http://www.yqcq.gov.cn/e/space/?userid=653667&yqcq.xml?feed_filter=20160916Na2Lz.html
http://www.yqcq.gov.cn/e/space/?userid=653669&yqcq.xml?feed_filter=20160916Ed7Ne.html
http://www.yqcq.gov.cn/e/space/?userid=653672&yqcq.xml?feed_filter=20160916Mw6Jb.html
http://www.yqcq.gov.cn/e/space/?userid=653674&yqcq.xml?feed_filter=20160916Jd2Xo.html
http://www.yqcq.gov.cn/e/space/?userid=653678&yqcq.xml?feed_filter=20160916Bg8Gm.html
http://www.yqcq.gov.cn/e/space/?userid=653680&yqcq.xml?feed_filter=20160916Lo0It.html
http://www.yqcq.gov.cn/e/space/?userid=653683&yqcq.xml?feed_filter=20160916Yj1Wy.html
http://www.yqcq.gov.cn/e/space/?userid=653686&yqcq.xml?feed_filter=20160916Jb3Us.html
http://www.yqcq.gov.cn/e/space/?userid=653688&yqcq.xml?feed_filter=20160916Mq1Ah.html
http://www.yqcq.gov.cn/e/space/?userid=653690&yqcq.xml?feed_filter=20160916Aa0Ip.html
http://www.yqcq.gov.cn/e/space/?userid=653693&yqcq.xml?feed_filter=20160916Yk8Ii.html
http://www.yqcq.gov.cn/e/space/?userid=653695&yqcq.xml?feed_filter=20160916Gu4Eg.html
http://www.yqcq.gov.cn/e/space/?userid=653699&yqcq.xml?feed_filter=20160916Mu5Ye.html
http://www.yqcq.gov.cn/e/space/?userid=653702&yqcq.xml?feed_filter=20160916Bo2Ir.html
http://www.yqcq.gov.cn/e/space/?userid=653705&yqcq.xml?feed_filter=20160916Yq7Kf.html
http://www.yqcq.gov.cn/e/space/?userid=653708&yqcq.xml?feed_filter=20160916Vd3Gd.html
http://www.yqcq.gov.cn/e/space/?userid=653710&yqcq.xml?feed_filter=20160916Zt1Ch.html
http://www.yqcq.gov.cn/e/space/?userid=653714&yqcq.xml?feed_filter=20160916Uc9Gh.html
http://www.yqcq.gov.cn/e/space/?userid=653716&yqcq.xml?feed_filter=20160916Pl2Or.html
http://www.yqcq.gov.cn/e/space/?userid=653719&yqcq.xml?feed_filter=20160916Lk4Kq.html
http://www.yqcq.gov.cn/e/space/?userid=653722&yqcq.xml?feed_filter=20160916Ir8Cv.html
http://www.yqcq.gov.cn/e/space/?userid=653725&yqcq.xml?feed_filter=20160916Xk7Gd.html
http://www.yqcq.gov.cn/e/space/?userid=653727&yqcq.xml?feed_filter=20160916Sn9El.html
http://www.yqcq.gov.cn/e/space/?userid=653730&yqcq.xml?feed_filter=20160916Gd9Fh.html
http://www.yqcq.gov.cn/e/space/?userid=653732&yqcq.xml?feed_filter=20160916Ka4Sv.html
http://www.yqcq.gov.cn/e/space/?userid=653735&yqcq.xml?feed_filter=20160916Sl1Jz.html
http://www.yqcq.gov.cn/e/space/?userid=653738&yqcq.xml?feed_filter=20160916Vr4Do.html
http://www.yqcq.gov.cn/e/space/?userid=653740&yqcq.xml?feed_filter=20160916Pb1Rk.html
http://www.yqcq.gov.cn/e/space/?userid=653743&yqcq.xml?feed_filter=20160916Fi3Xv.html
http://www.yqcq.gov.cn/e/space/?userid=653746&yqcq.xml?feed_filter=20160916Yx5Qr.html
http://www.yqcq.gov.cn/e/space/?userid=653749&yqcq.xml?feed_filter=20160916Md4Ks.html
http://www.yqcq.gov.cn/e/space/?userid=653752&yqcq.xml?feed_filter=20160916Hx9Ko.html
http://www.yqcq.gov.cn/e/space/?userid=653756&yqcq.xml?feed_filter=20160916Af2Sx.html
http://www.yqcq.gov.cn/e/space/?userid=653759&yqcq.xml?feed_filter=20160916Wk3Tj.html
http://www.yqcq.gov.cn/e/space/?userid=653762&yqcq.xml?feed_filter=20160916Gm3Da.html
http://www.yqcq.gov.cn/e/space/?userid=653765&yqcq.xml?feed_filter=20160916Ht9Uz.html
http://www.yqcq.gov.cn/e/space/?userid=653768&yqcq.xml?feed_filter=20160916Mr2Cg.html
http://www.yqcq.gov.cn/e/space/?userid=653771&yqcq.xml?feed_filter=20160916Mk2My.html
http://www.yqcq.gov.cn/e/space/?userid=653774&yqcq.xml?feed_filter=20160916Qx8Kk.html
http://www.yqcq.gov.cn/e/space/?userid=653777&yqcq.xml?feed_filter=20160916Ou1Zi.html
http://www.yqcq.gov.cn/e/space/?userid=653778&yqcq.xml?feed_filter=20160916Vj3Lg.html
http://www.yqcq.gov.cn/e/space/?userid=653782&yqcq.xml?feed_filter=20160916Ut5Ee.html
http://www.yqcq.gov.cn/e/space/?userid=653784&yqcq.xml?feed_filter=20160916Eg4Ak.html
http://www.yqcq.gov.cn/e/space/?userid=653788&yqcq.xml?feed_filter=20160916Hg8Lt.html
http://www.yqcq.gov.cn/e/space/?userid=653789&yqcq.xml?feed_filter=20160916Bn5Be.html
http://www.yqcq.gov.cn/e/space/?userid=653793&yqcq.xml?feed_filter=20160916Np7Yr.html
http://www.yqcq.gov.cn/e/space/?userid=653794&yqcq.xml?feed_filter=20160916Cd9Ii.html
http://www.yqcq.gov.cn/e/space/?userid=653798&yqcq.xml?feed_filter=20160916St0Zi.html
http://www.yqcq.gov.cn/e/space/?userid=653800&yqcq.xml?feed_filter=20160916Dv7Jr.html
http://www.yqcq.gov.cn/e/space/?userid=653803&yqcq.xml?feed_filter=20160916Fv2Se.html
http://www.yqcq.gov.cn/e/space/?userid=653807&yqcq.xml?feed_filter=20160916Hj7Eo.html
http://www.yqcq.gov.cn/e/space/?userid=653808&yqcq.xml?feed_filter=20160916Mo2Bn.html
http://www.yqcq.gov.cn/e/space/?userid=653812&yqcq.xml?feed_filter=20160916Zo4Xz.html
http://www.yqcq.gov.cn/e/space/?userid=653815&yqcq.xml?feed_filter=20160916Rn4Aq.html
http://www.yqcq.gov.cn/e/space/?userid=653817&yqcq.xml?feed_filter=20160916Gp4Pu.html
http://www.yqcq.gov.cn/e/space/?userid=653820&yqcq.xml?feed_filter=20160916Lg5Vi.html
http://www.yqcq.gov.cn/e/space/?userid=653823&yqcq.xml?feed_filter=20160916Xj8Wm.html
http://www.yqcq.gov.cn/e/space/?userid=653826&yqcq.xml?feed_filter=20160916Ua9Vl.html
http://www.yqcq.gov.cn/e/space/?userid=653829&yqcq.xml?feed_filter=20160916Gf5Jd.html
http://www.yqcq.gov.cn/e/space/?userid=653832&yqcq.xml?feed_filter=20160916Ft1Kp.html
http://www.yqcq.gov.cn/e/space/?userid=653834&yqcq.xml?feed_filter=20160916Xm4Lt.html
http://www.yqcq.gov.cn/e/space/?userid=653837&yqcq.xml?feed_filter=20160916Qy2On.html
http://www.yqcq.gov.cn/e/space/?userid=653841&yqcq.xml?feed_filter=20160916Ax9Ox.html
http://www.yqcq.gov.cn/e/space/?userid=653843&yqcq.xml?feed_filter=20160916Rz0Hj.html
http://www.yqcq.gov.cn/e/space/?userid=653845&yqcq.xml?feed_filter=20160916Vi4Kd.html
http://www.yqcq.gov.cn/e/space/?userid=653848&yqcq.xml?feed_filter=20160916Dz6Fr.html
http://www.yqcq.gov.cn/e/space/?userid=653849&yqcq.xml?feed_filter=20160916He9Rw.html
http://www.yqcq.gov.cn/e/space/?userid=653853&yqcq.xml?feed_filter=20160916Mf9Gc.html
http://www.yqcq.gov.cn/e/space/?userid=653855&yqcq.xml?feed_filter=20160916Lj2Rw.html
http://www.yqcq.gov.cn/e/space/?userid=653858&yqcq.xml?feed_filter=20160916Sx7Gc.html
http://www.yqcq.gov.cn/e/space/?userid=653862&yqcq.xml?feed_filter=20160916Cw3Bb.html
http://www.yqcq.gov.cn/e/space/?userid=653864&yqcq.xml?feed_filter=20160916Ua7Mn.html
http://www.yqcq.gov.cn/e/space/?userid=653867&yqcq.xml?feed_filter=20160916Ob1Ji.html
http://www.yqcq.gov.cn/e/space/?userid=653870&yqcq.xml?feed_filter=20160916Yw8Iy.html
http://www.yqcq.gov.cn/e/space/?userid=653873&yqcq.xml?feed_filter=20160916Dy3Wf.html
http://www.yqcq.gov.cn/e/space/?userid=653875&yqcq.xml?feed_filter=20160916Yq6Sl.html
http://www.yqcq.gov.cn/e/space/?userid=653879&yqcq.xml?feed_filter=20160916Gx8Sc.html
http://www.yqcq.gov.cn/e/space/?userid=653881&yqcq.xml?feed_filter=20160916Fk7Gt.html
http://www.yqcq.gov.cn/e/space/?userid=653884&yqcq.xml?feed_filter=20160916Cf0Ui.html
http://www.yqcq.gov.cn/e/space/?userid=653887&yqcq.xml?feed_filter=20160916Kr8Uo.html
http://www.yqcq.gov.cn/e/space/?userid=653891&yqcq.xml?feed_filter=20160916Ki9En.html
http://www.yqcq.gov.cn/e/space/?userid=653893&yqcq.xml?feed_filter=20160916La4Yi.html
http://www.yqcq.gov.cn/e/space/?userid=653896&yqcq.xml?feed_filter=20160916Cw6Bf.html
http://www.yqcq.gov.cn/e/space/?userid=653898&yqcq.xml?feed_filter=20160916Wk8Ui.html
http://www.yqcq.gov.cn/e/space/?userid=653901&yqcq.xml?feed_filter=20160916In4Jv.html
http://www.yqcq.gov.cn/e/space/?userid=653903&yqcq.xml?feed_filter=20160916Le9Og.html
http://www.yqcq.gov.cn/e/space/?userid=653906&yqcq.xml?feed_filter=20160916Ko0Xd.html
http://www.yqcq.gov.cn/e/space/?userid=653909&yqcq.xml?feed_filter=20160916Wk5Gm.html
http://www.yqcq.gov.cn/e/space/?userid=653912&yqcq.xml?feed_filter=20160916Qw2Hs.html
http://www.yqcq.gov.cn/e/space/?us

作者:fwlhy1216 发表于2016/9/16 21:48:34 原文链接
阅读:96 评论:0 查看评论

Android自定义控件一(继承自View)

$
0
0

从现在开始,将认真对待写博客这件事,以前自己写的博客大多都是作为自己对知识的记录,可读性不强,现在不仅作为记录,也希望把自己知道的一些知识共享,共同进步。
对于Android自定义控件,这是Android开发进阶的一个重要技能,从此踏入自定义的门槛。今天就先继承自View,实现两个比较基本的自定义控件。先看效果图:
这里写图片描述
自定义控件一般需要如下几步:
1、自定义属性。因为在自定义控件的过程中往往需要在控件上添加我们自己希望的属性。
2、在自定义控件中获取我们自定义的属性。
3、自定义OnMeasure()方法。(可选,因为系统默认了一个实现方法,许多时候我们并不需要处理这个方法)
4、自定义onDraw()方法。(在屏幕上绘制出控件的模样)
5、在布局文件中引用类型
由于上面两个控件自定义的操作步骤是相同的,所以两个控件就一起说了。
第一步自定义属性:
每个自定义的属性都需要给定一个属性值得类型,几种类型已经在下面代码中标识出来

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <!--
    这个是第一个的自定义属性,name表示属性的名称,format表示属性值得类型
    color:颜色            比如android:textColor="#ffffff"
    dimension:尺寸        比如 android:textSize="16sp"
    enum:枚举类型          比如 android:layout_width="wrap_content"
    boolean:             true 或者 false
    flag:位或类型          用 | 连接起来, 比如android:layout_gravity="center|vertical"
    float:浮点类型
    fraction:百分数
    reference:引用类型     比如 android:textColor="@color/mycolor"
    string:字符串类型
    -->
    <declare-styleable name="ProgressView">
        <attr name="colorWidth" format="dimension"/>
        <attr name="noColorWidth" format="dimension"/>
        <attr name="color" format="color"/>
        <attr name="width" format="dimension"/>
        <attr name="speed" format="enum">
            <enum name="fast" value="5"/>
            <enum name="middle" value="3"/>
            <enum name="slow" value="1"/>
        </attr>
    </declare-styleable>

    <declare-styleable name="ClockView">
        <attr name="hourColor" format="color"/>
        <attr name="minuteColor" format="color"/>
        <attr name="secondColor" format="color"/>
        <attr name="tableColor" format="color"/>
    </declare-styleable>
</resources>

下面是第二三四步的代码,首先来看第一个自定义控件的代码。说明已经在代码中标注出来,主要实现的是onDraw()方法用来绘制控件,这部分有时候需要考虑的是数学问题,而在这个控件中实现不断向右滑动就是利用科count的不断连续性的改变实现的。

public class ProgressView extends View {

    //下面的几个变量用来存储各个属性值。
    int colorWidth;
    int noColorWidth;
    int color;
    Paint paint;
    int count = 0;
    int screenWidth;
    int speed;
    int width;
    public ProgressView(Context context) {
        super(context);
    }

    public ProgressView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
    public ProgressView(Context context, AttributeSet attrs) {
        super(context, attrs);

        //通过typedArray来获取各个属性值
        TypedArray array = context.obtainStyledAttributes(attrs,R.styleable.ProgressView);
        colorWidth = array.getDimensionPixelSize(R.styleable.ProgressView_colorWidth,20);
        noColorWidth = array.getDimensionPixelSize(R.styleable.ProgressView_noColorWidth,20);
        color = array.getColor(R.styleable.ProgressView_color, Color.BLUE);
        speed = array.getInt(R.styleable.ProgressView_speed,3);
        width = array.getDimensionPixelSize(R.styleable.ProgressView_width,10);

        //初始化画笔
        paint = new Paint();
        paint.setColor(color);
        paint.setStrokeWidth(width);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        screenWidth = getWidth();
        int start = count % (colorWidth + noColorWidth);
        start = start - (colorWidth + noColorWidth);
        while (start < screenWidth) {
            canvas.drawLine(start,getHeight()/2,start+colorWidth,getHeight()/2,paint);
            start += colorWidth+noColorWidth;
        }
        count += speed;
        count %= (colorWidth+noColorWidth);
        /*
        每当绘制一次count增加,然后调用invalidate(),会重新执行onDraw方法,而每次绘制会根据count的值绘制
        到不同的位置,从而就达到了动态的效果。
        这里有两个方法postInvalidate()和invalidate()方法.其中前者是在工作线程中被调用,
        而后者在UI线程中被调用
        */
        invalidate();
    }
}

下面的代码是实现那个时钟控件。

package com.zwbin.custom;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;

/**
 * Created by wenbin on 16/9/14.
 */
public class ClockView extends View {

    int hourColor;
    int minuteColor;
    int secondColor;
    int tableColor;

    Paint paint;

    public ClockView(Context context) {
        super(context);
    }

    public ClockView(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.ClockView);
        hourColor = typedArray.getColor(R.styleable.ClockView_hourColor, Color.RED);
        minuteColor = typedArray.getColor(R.styleable.ClockView_minuteColor, Color.BLUE);
        secondColor = typedArray.getColor(R.styleable.ClockView_secondColor, Color.GREEN);
        tableColor = typedArray.getColor(R.styleable.ClockView_tableColor, Color.GRAY);

        paint = new Paint();
    }

    public ClockView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        //开始画表盘
        paint.setColor(tableColor);
        paint.setStrokeWidth(3);
        paint.setStyle(Paint.Style.STROKE);
        int width = getWidth();
        int height = getHeight();
        int radius = Math.min(width/2,height/2);
        canvas.drawCircle(width/2,height/2,radius,paint);
        paint.setStrokeWidth(8);
        //表盘最长的四条线
        for (int i = 0;i < 4;i++) {
            double degree = Math.PI/2 * i;
            double sin = Math.sin(degree);
            double cos = Math.cos(degree);
            canvas.drawLine((int)(radius*sin + width/2),
                    (int)(height/2-radius*cos),
                    (int)((radius-60)*sin + width/2),
                    (int)(height/2 - (radius-60)*cos),
                    paint);
        }
        //表盘第二长的12条线
        for (int i = 0;i < 12;i++) {
            double degree = Math.PI/6 * i;
            double sin = Math.sin(degree);
            double cos = Math.cos(degree);
            canvas.drawLine((int)(radius*sin + width/2),
                    (int)(height/2-radius*cos),
                    (int)((radius-40)*sin + width/2),
                    (int)(height/2 - (radius-40)*cos),
                    paint);
        }
        //表盘最短的60条线
        for (int i = 0;i < 60;i++) {
            double degree = Math.PI/30 * i;
            double sin = Math.sin(degree);
            double cos = Math.cos(degree);
            canvas.drawLine((int)(radius*sin + width/2),
                    (int)(height/2-radius*cos),
                    (int)((radius-20)*sin + width/2),
                    (int)(height/2 - (radius-20)*cos),
                    paint);
        }
        //开始画中心点
        paint.setStrokeWidth(30);
        canvas.drawPoint(width/2,height/2,paint);

        Calendar calendar = Calendar.getInstance();
        int hour = calendar.get(Calendar.HOUR);
        int mimute = calendar.get(Calendar.MINUTE);
        int second = calendar.get(Calendar.SECOND);
        //开始画时针
        int hourRadius = radius/3;
        paint.setStrokeWidth(30);
        paint.setColor(hourColor);
        canvas.drawLine(width/2,
                height/2,
                (int)(width/2+hourRadius*Math.sin(hour*Math.PI/6)),
                (int)(height/2-hourRadius*Math.cos(hour*Math.PI/6)),
                paint);
        //开始画分针
        int minuteRadius = radius/2;
        paint.setStrokeWidth(20);
        paint.setColor(minuteColor);
        canvas.drawLine(width/2,
                height/2,
                (int)(width/2+minuteRadius*Math.sin(mimute*Math.PI/30)),
                (int)(height/2-minuteRadius*Math.cos(mimute*Math.PI/30)),
                paint);
        //开始画秒针
        int secondRadius = radius*2/3;
        paint.setStrokeWidth(10);
        paint.setColor(secondColor);
        canvas.drawLine(width/2,
                height/2,
                (int)(width/2+secondRadius*Math.sin(second*Math.PI/30)),
                (int)(height/2-secondRadius*Math.cos(second*Math.PI/30)),
                paint);
        invalidate();
    }
}

可以很明显得看到,代码的相似度很高,最主要的区别就是在onDraw中绘制表的部分,这部分是根据相关坐标来绘制圆圈、直线、点组成的。也和上一个自定义控件一样,每次绘制完成会调用invalidate()来进行重新绘制,表盘位置不变,时针、分针、秒针会根据时间绘制到不同的位置,连续进行绘制就会出现动态移动的效果。
下面进行最后一步,在布局文件中使用。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res/com.zwbin.custom"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.zwbin.custom.MainActivity">

    <com.zwbin.custom.ProgressView
        android:layout_width="match_parent"
        android:layout_height="50dp"
        app:colorWidth="50dp"
        app:noColorWidth="50dp"
        app:speed="middle"
        app:color="#FF0000"
        app:width="10dp"/>
    <com.zwbin.custom.ClockView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

至此这两个基础的控件绘制完成了,下一篇会对这一篇的代码进行详解。

作者:zwbzwbzwbzwbzwbzwb 发表于2016/9/16 23:59:02 原文链接
阅读:51 评论:0 查看评论

一路走来,从自学到工作这一年我学到了什么?

$
0
0

   应driphp.com Eric群主再三邀请,给大家做一个分享,同时也是对自己工作的总结。

   先简单介绍下自己,我是David,和群主是大学同班同学,曾将和群主一起创业。我大三开始自学JAVA、Android ,大三结束后在某创业公司实习半年,后来通过校招到某一线Andorid OS 厂商工作。到现在工作也一年多了,今天打算把自己看到了,经历的觉得有用的东西分享给大家。在编程届我还是个小学生,所以今天的分享如果有不对的地方,还请各位大牛指正。

 

一、关于自学和入门

   我有两个同事,他们大学学的是机械、化学,但是他们的编程能力是在我这个科班出身的之上的,为什么?

   自学和勤奋

   虽然我是计算机专业,但是大家都了解学校教给你的是远远不够的,只能靠自学。首先给自己定一个方向,毕业后是想做服务端、客户端、前端还是算法或者其他自己感兴趣的方向。这里要强调一下,兴趣真的很重要,因为你会发现有时候自学编程真的很枯燥,如果没有兴趣真的坚持不下来。我给自己选择的是Android 应用开发,因为自己买的一千左右的Andorid手机就有像iphone一样的体验,这个系统太神奇了。而且Android app开发当时这个方向很火,很新。同时Android是Google大大的开发的系统,底层代码又是开源的。

   看到开发Android需要JAVA语言基础,于是开始从网上找了JAVA资料,我的启蒙老师是韩顺平(现在连名字都记不清了,现百度的。但是真的很感谢这个人。他的教学视频质量很多,就算像我一样很差的人也能轻松入门)。韩老师的课程讲的比较基础,而且是带着你一行一行的敲。于是那一段时间,除了上课的时间我就抱着电脑到实验室去看视频,一边看一边敲。先是讲JAVA语法,后面开始有实战项目。

    入门的时候推荐大家看视频而不是书,视频有更好的带入性和互动性。买本几百页的书估计看十分钟就睡着了。而且目前国内像慕课网,极客学院、51CTO之类的Online教育网站视频质量都很高。看视频的时候要开始做笔记,可以开一个CSDN博客,把自己的总结写上去,时不时还会有人给你点赞。这里推荐一下CSDN这个平台,有人推荐程序员要搭建一个个人blog,但是我觉得个人blog可能互动性不如CSDN。你在写博客的同时也能看到大牛们的博客,CSDN上面的博文质量很高,而且每天都会有大牛讲各种前沿的技术分析,酷炫的自定义控件、深入剖析某个框架,牛人很多。

  看过视频之后可以自己做个小项目,可以比着市面上比较流行的项目去做,也可以以参加比赛的目的去做。同时自己也可以买几本对应语言的比较经典的书籍。JAVA的话,推荐《Thinking in JAVA》、《疯狂JAVA系列》、《JAVA核心技术》、《Effective java》。看书应该能够给你更多的时间去思考,书里也会有比较深入的东西,更注重的是理论。

  其实,对于入门来说也没有什么捷径,就是勤奋和坚持。每个人都要经历这个过程。

 

二、关于找工作

 基础打好了,就可以去找工作了。找实习的时候需要先对自己的找的方向面试问题大概了解一下。找实习的时候主要是看你的基础还有自学能力。包括语言语法,简单的性能优化,项目中遇到实际问题,通过算法题考察你的思维敏锐度。这种东西其实面多了,总结总结自然就会了,来回来去都是那些东西。也可以提前看看前辈的面试经验贴。算法这个需要长期的积累,校招还是很看重的,当时面某团,一面问的JAVA和Android技术轻松应对,二面问的很复杂的算法当场就跪了。算法要多刷题,好像没啥捷径。推荐Leetcode。找实习大厂不好进,除非你的基础特别好,或者学校特别好。

 

关于实习的选择:最重要的是看能不能学到东西,而不是工资。当时我拿到了两个实习offer 工资差了大概1000块。但是我选择了工资少的那个。因为这个团队的人经验都很丰富,而且公司运作了4年了,有技术积累。后来我觉得我的选择是对的,团队里面有2个技术大牛,各种博客之星各种github开源大牛。可想而知天天坐在这种人身边,和这种人一起写代码自己的提高也很快。

 

关于校招:去年9月开始边工作边校招。北京所有的大公司基本都走了一遍但是没有一个公司收留我。总结失败的经历是因为自己的基础知识比较差,平时对计算机基础关注较少,可以说是因为大一大二的时候没有好好上课。而项目方面对内存、性能优化以及底层的实现了解的也比较少。当时很沮丧,就放弃了。又回到了之前实习的公司继续工作,开始有点混日子了,瞬间没有目标了。突然有天和某个HR聊起来,他的一句话:“在互联网圈里混,你这学历也不行,现在你公司也不行。以后不好混啊!”是啊,进个大公司对自己发展还是有很多好处的,无论是眼界还是技术的沉淀。于是继续边实习边学习,那段时间自己很勤奋,主要精力放在了基础知识、Volley,ImageLoader开源框架的理解、性能内存优化以及JAVA语言深入理解。于是在16年年初通过学长的推荐,面试过了一线的Android os厂商。

 

三、我学到了什么?

1.    严谨和标准

严格的代码review,每个commit 都需要经过师父的review和QA同学的验证。

经常因为类命名被骂。因为代码结构被骂。的确,代码写完后还会有团队里其他人在看,好的代码结构和命名是很有必要的。

     2.独立深入思考问题的能力

最近发现无论是技术还是管理上面牛的人做事情都特别冷静,能够安静的思考问题。无论是遇到多么复杂的问题,无论环境多么嘈杂。

记得有个BUG,自己2周才解决,写了4行代码,但是看了将近几千行。从Android framework 到selinux ,虽然很煎熬,但是学到了很多。独立分析问题的能力是一个优秀的程序员必须具备的。但是,作为初级RD,如果你遇到了一个问题很久没解决,一定要向他人求教,也许有时候他人的一句话,就能解决这个问题。

解决了一个小BUG,是否就这样完事儿了?要深入去理解。为什么我加这一行就能解决。

最近在慢慢开始看Android framework的东西。虽然很枯燥,但真正看懂的时候你会发现Android的设计很奇妙的。我喜欢深入去剖析某个东西。准备面试的时候看了Volley源码,给自己加了很多分。

   3.做一个有追求的程序员

遇到问题不要只想着打补丁的方式去解决,比如遇到一个NullPointException,不要只做一个判断,然后catch住。也许只有你觉得这能解决这个问题。只是你觉得?可能并没有cover到所有的case.而且如果有其他人解决的时候会很难理解你的做法。如果一个项目到处都是这种补丁,可想是有多么糟糕。你做的就是应该去找到为什么会抛出这个exception,然后正面的去解决。遇到问题不要规避,正面应对。

追求极致。做个靠谱的工程师。自己发现的BUG,你会不会解决?自己写的代码是否经常review?是否经常关注用户对自己做的功能的反馈。优秀的程序员和普通的程序员也许只差一点,责任心。

    4.勤奋

很高兴在这个团队,并没有很多天生丽质的大牛,学校都一般。组里技术最好的几个人永远都是最晚走的,周末也经常在公司学习。我们leader也是以勤奋出名,当时在新版本上线时候也经常一个人为了解决一个问题待到两三点。目前他已经不写代码了,但是写了N年代码让他变得冷静,逻辑性强,在管理层也做的风生水起,目前已经实现财富自由,还不到30岁。如果你也像我一样不聪明,目前资历一般,那就勤奋起来吧。下班别人都走了,咱们可以在公司总结一下今天学到了什么,看看github上面有什么好玩的,看看最近热门的博客。年轻的时候就应该是自己多沉淀的时候。

5.语言表达能力

      遇到问题,该怎么优雅的向他人请教?团队大了就经常涉及到和其他组的人沟通。能否把问题表述清楚?能否让其让人乐意帮你?发邮件的时候,能否考虑全面,用最少的文字将问题说清楚。现在我每次发重要的邮件还是需要师父去review。这还是很需要功夫去磨练的。平时多听听大牛是怎么讨论问题的。也可以多读书,多写写博客。毕竟我们不会写一辈子代码。

6.英语

     这个就不多说了,目前看到的官方教程全是英文的,源码注释也是英文的。这个感觉不用刻意去学,只要多看多积累就好了。之前commit message用中文,现在都换成英文。注释啥的也都换成英文去。

7.给自己留下点什么。

     Github多刷刷,博客多上上,知乎多水水。一来是自己积累知识,二来提升自己的知名度,名气大了在这个圈子里面就好混了。

8.多总结,多沉淀

    无论再忙也找给自己找时间去总结,去思考。工作多年的程序员也会有很大的差别,在大公司的也有很多渣渣。

9.热爱编程,热爱生活。

你写的代码不仅仅能够给你高工资,还能给亿万用户带来便利。

 

四、关于DriPhp

群主是个很有分享精神的人,大学的时候也建立的很多学习小组,都是考试之前突击的那种,最后小组里面的人都没挂科,哈哈!所以在这里要感谢群主能给我们这么一个平台,每日一问,日积月累。

 

就暂时分享这么多,一时不知道写什么了? 以后欢迎各位大牛们在群里多多做分享,多多讨论!希望各位都能够成为改变世界的程序员,加油!

 

 

作者:Davidluo001 发表于2016/9/17 0:11:16 原文链接
阅读:101 评论:2 查看评论

急速开发系列——Retrofit实现持久化Cookie的三种方案

$
0
0

在上一文中,我们提到retrofit 2.0中如何实现非持久化cookie的两种方案,但并未做过深的解释。
现在我们重点关注JavaNetCookieJar实现非持久化cookie背后的原理。

话不多说,步入正题。


非持久化Cookie实现分析

首先来看上文中提到的非持久化cookie的实现:

 public void setCookies(OkHttpClient.Builder builder) {
        CookieManager cookieManager = new CookieManager();
        cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
        builder.cookieJar(new JavaNetCookieJar(cookieManager));
    }

现在我们就以这段代码为起点来研究为什么这几行代码就实现了非持久化cookie呢?不难先发现此处实现cookie的关键就是cookieJar(),我们就以该方法切入。
首先来看该方法的源码:

     //设置cookie处理器,如果没设置,则使用CookieJar.NO_COOKIES作为默认的处理器
    public Builder cookieJar(CookieJar cookieJar) {
      if (cookieJar == null) throw new NullPointerException("cookieJar == null");
      this.cookieJar = cookieJar;
      return this;
    }

通过该方法我们知道这里的关键就在于CookieJar接口,来看看这个接口的定义:

public interface CookieJar {
 //默认的cookie处理器,不接受任何cookie
  CookieJar NO_COOKIES = new CookieJar() {
    @Override public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
    }

    @Override public List<Cookie> loadForRequest(HttpUrl url) {
      return Collections.emptyList();
    }
  };


   //根绝cookie处理策略,保存响应中的cookie
  void saveFromResponse(HttpUrl url, List<Cookie> cookies);

  //为请求添加cookie 
  List<Cookie> loadForRequest(HttpUrl url);
}

该接口非常简单,提供了保存和加载cookie的两个方法loadForRequest(HttpUrl url)saveFromResponse(HttpUrl url,List<Cookie> cookies),这就意味这我们可以自行实现接口来实现对cookie管理。到这里想必各位可能已经在想“我们自行实现该接口来将cookie保存到本地,使用的时候再从本地读取,这样不久实现cookie持久化了么?”,这当然没问题,但我们先继续往下看。

除此之外,该接口中存在一个默认的实现NO_COOKIES。

接下来,我们来看看该接口的另外一个实现类JavaNetCookieJar,它本质上只是java.net.CookieHandler的代理类。同样,来看一下JavaNetCookieJar中的源码:

public final class JavaNetCookieJar implements CookieJar {
  private final CookieHandler cookieHandler;

  public JavaNetCookieJar(CookieHandler cookieHandler) {
    this.cookieHandler = cookieHandler;
  }


  @Override public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
    if (cookieHandler != null) {
      List<String> cookieStrings = new ArrayList<>();
      for (Cookie cookie : cookies) {//遍历cookie集合
        cookieStrings.add(cookie.toString());
      }
      Map<String, List<String>> multimap = Collections.singletonMap("Set-Cookie", cookieStrings);
      try {
      //具体的保存工作交给cookieHandler去处理
        cookieHandler.put(url.uri(), multimap);
      } catch (IOException e) {
        Internal.logger.log(WARNING, "Saving cookies failed for " + url.resolve("/..."), e);
      }
    }
  }

  @Override public List<Cookie> loadForRequest(HttpUrl url) {
    // The RI passes all headers. We don't have 'em, so we don't pass 'em!
    Map<String, List<String>> headers = Collections.emptyMap();
    Map<String, List<String>> cookieHeaders;
    try {
      //从cookieHandler中取出cookie集合。
      cookieHeaders = cookieHandler.get(url.uri(), headers);
    } catch (IOException e) {
      Internal.logger.log(WARNING, "Loading cookies failed for " + url.resolve("/..."), e);
      return Collections.emptyList();
    }

    List<Cookie> cookies = null;
    for (Map.Entry<String, List<String>> entry : cookieHeaders.entrySet()) {
      String key = entry.getKey();
      if (("Cookie".equalsIgnoreCase(key) || "Cookie2".equalsIgnoreCase(key))
          && !entry.getValue().isEmpty()) {
        for (String header : entry.getValue()) {
          if (cookies == null) cookies = new ArrayList<>();
          cookies.addAll(decodeHeaderAsJavaNetCookies(url, header));
        }
      }
    }

    return cookies != null
        ? Collections.unmodifiableList(cookies)
        : Collections.<Cookie>emptyList();
  }


   //将请求Header转为OkHttp中HttpCookie
  private List<Cookie> decodeHeaderAsJavaNetCookies(HttpUrl url, String header) {
    List<Cookie> result = new ArrayList<>();
    for (int pos = 0, limit = header.length(), pairEnd; pos < limit; pos = pairEnd + 1) {
      //具体转换过程在此不做展示
    }
    return result;
  }
}

上面的代码非常简单,其核心无非在于通过CookieHandler实现对cookie的保存和取值。既然,真正的工作类是CookieHandler,那我们就重点关注CookieHandler.

public abstract class CookieHandler {

    private static CookieHandler cookieHandler;

    public synchronized static CookieHandler getDefault() {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            sm.checkPermission(SecurityConstants.GET_COOKIEHANDLER_PERMISSION);
        }
        return cookieHandler;
    }

    public synchronized static void setDefault(CookieHandler cHandler) {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            sm.checkPermission(SecurityConstants.SET_COOKIEHANDLER_PERMISSION);
        }
        cookieHandler = cHandler;
    }

    public abstract Map<String, List<String>>
        get(URI uri, Map<String, List<String>> requestHeaders)
        throws IOException;

    public abstract void
        put(URI uri, Map<String, List<String>> responseHeaders)
        throws IOException;
}

我们发现CookieHandler是个抽象类,其实现类就是我们上面在非持久化Cookie中用到的CookieManager,没办法,我们在此转移焦点至CookieManager:

public class CookieManager extends CookieHandler
{
    private CookiePolicy policyCallback;//cookie处理策略
    private CookieStore cookieJar = null;//cookie存储

    public CookieManager() {
        this(null, null);
    }

    //在这里我们可以指定cookie存储方式及cookie处理策略
    public CookieManager(CookieStore store,
                         CookiePolicy cookiePolicy)
    {
        // use default cookie policy if not specify one
        policyCallback = (cookiePolicy == null) ? CookiePolicy.ACCEPT_ORIGINAL_SERVER
                                                : cookiePolicy;

        // 如果没有指定持久化方式,则默认使用内存持久化。
        if (store == null) {
            cookieJar = new InMemoryCookieStore();
        } else {
            cookieJar = store;
        }
    }

    //指定cookie处理策略
    public void setCookiePolicy(CookiePolicy cookiePolicy) {
        if (cookiePolicy != null) policyCallback = cookiePolicy;
    }

    public CookieStore getCookieStore() {
        return cookieJar;
    }


    //获取cookie
    public Map<String, List<String>>
        get(URI uri, Map<String, List<String>> requestHeaders)
        throws IOException
    {
       //... 省略多行代码

        Map<String, List<String>> cookieMap =
                        new java.util.HashMap<String, List<String>>();
      //... 省略多行代码
        for (HttpCookie cookie : cookieJar.get(uri)) {
            //... 省略多行代码
        }

        // apply sort rule (RFC 2965 sec. 3.3.4)
        List<String> cookieHeader = sortByPath(cookies);

        cookieMap.put("Cookie", cookieHeader);
        return Collections.unmodifiableMap(cookieMap);
    }

    //保存cookie
    public void
        put(URI uri, Map<String, List<String>> responseHeaders)
        throws IOException
    {
        //... 省略多行代码
    PlatformLogger logger = PlatformLogger.getLogger("java.net.CookieManager");
        for (String headerKey : responseHeaders.keySet()) {
            // RFC 2965 3.2.2, key must be 'Set-Cookie2'
            // we also accept 'Set-Cookie' here for backward compatibility
            if (headerKey == null
                || !(headerKey.equalsIgnoreCase("Set-Cookie2")
                     || headerKey.equalsIgnoreCase("Set-Cookie")
                    )
                )
            {
                continue;
            }

            for (String headerValue : responseHeaders.get(headerKey)) {
                try {
                    List<HttpCookie> cookies;
                    try {
                        cookies = HttpCookie.parse(headerValue);
                    } catch (IllegalArgumentException e) {
                        // Bogus header, make an empty list and log the error
                        cookies = java.util.Collections.emptyList();
                        if (logger.isLoggable(PlatformLogger.Level.SEVERE)) {
                            logger.severe("Invalid cookie for " + uri + ": " + headerValue);
                        }
                    }
                    for (HttpCookie cookie : cookies) {
                        if (cookie.getPath() == null) {
                            //... 省略多行代码
                            cookie.setPath(path);
                        }

                        if (cookie.getDomain() == null) {
                            //... 省略多行代码
                            cookie.setDomain(host);
                        }

                        //... 省略多行代码
                            if (shouldAcceptInternal(uri, cookie)) {
                                cookieJar.add(uri, cookie);
                            }
                    }
                } catch (IllegalArgumentException e) {
                    // invalid set-cookie header string
                    // no-op
                }
            }
        }
    }



}

在CacheManager中,需要重点关注的便是policyCallback和cookieJar两个成员变量。分别来看看这二者做了什么?

cookie处理策略
cookie的处理策略由CookiePolicy接口确定,该接口中预置了三种处理策略:ACCEPT_ALL,ACCEPT_NONE及ACCEPT_SERVER,分别用于接受所有cookie,不接受cookie,只接受初始服务器的cookie。

cookie存储
cookie的存储则由CookieStore接口负责,该接口目前存在唯一的实现类InMemoryCookieStore,通过该实现类的名字也大概猜的出它将cookie存在内存中了,同样我们简单的浏览一下其源码:

class InMemoryCookieStore implements CookieStore {
    private List<HttpCookie> cookieJar = null;
    private Map<String, List<HttpCookie>> domainIndex = null;
    private Map<URI, List<HttpCookie>> uriIndex = null;

    // use ReentrantLock instead of syncronized for scalability
    private ReentrantLock lock = null;


    /**
     * The default ctor
     */
    public InMemoryCookieStore() {
        cookieJar = new ArrayList<HttpCookie>();
        domainIndex = new HashMap<String, List<HttpCookie>>();
        uriIndex = new HashMap<URI, List<HttpCookie>>();

        lock = new ReentrantLock(false);
    }

   //保存cookie
    public void add(URI uri, HttpCookie cookie) {
        // pre-condition : argument can't be null
        if (cookie == null) {
            throw new NullPointerException("cookie is null");
        }


        lock.lock();
        try {
            // 首先移除已经存在的cookie
            cookieJar.remove(cookie);

            // 缓存时间不为0
            if (cookie.getMaxAge() != 0) {
                cookieJar.add(cookie);
                // 保存到域索引中
                if (cookie.getDomain() != null) {
                    addIndex(domainIndex, cookie.getDomain(), cookie);
                }
                //保存到url索引中
                if (uri != null) {
                    // add it to uri index, too
                    addIndex(uriIndex, getEffectiveURI(uri), cookie);
                }
            }
        } finally {
            lock.unlock();
        }
    }

}

到现在我们已经弄明白非持久化Cookie的原理,这里用一张类图来概括一下:
此处输入图片的描述

从设计的来说,这里也充分体现了面向抽象编程,单一职责理念等。对这些设计原则不明白的可以看我以前写的文章。


持久化Cookie实现

自定义InDiskCookieStore实现持久化Cookie

通过上面的分析,我们最终知道非持久化Cookie的存储靠InMemoryCookieStore实现,除此之外,我们发现CookieManager中也可以指定另外的CookieStore的实现。这样看来,我们只需要自定义InDiskCookieStore实现CookieStore,并将其设置给CookieManager就可以实现Cookie的持久化了。接下来,我们仿照inMemoryCookieStore来实现自己的InDiskCookieStore。

(稍后补码)

自定义拦截器实现持久化Cookie

通过自定义拦截器实现Cookie持久化的思路我们已经在上一篇文章说过,就不多做解释了,直接来看代码即可:

(稍后补码)

自定义CookieJar实现持久化Cookie

自定义CookieJar中对Cookie的保存和加载实现和自定义拦截器的方式一致,故不做详细的说明了。后面直接上代码。


总结

到现在我们彻底的了解Cookie的持久化技术,不难发现这三种持久化实现方案原理都是大同小异。

作者:dd864140130 发表于2016/9/17 0:13:16 原文链接
阅读:52 评论:0 查看评论

Android Multimedia框架总结(十)Stagefright框架之音视频输出过程

$
0
0

转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52560012

前言:上篇文中最后介绍了数据解码放到Buffer过程,今天分析的是stagefright框架中音视频输出过程:
先看下今天的Agenda:

  • 一张图回顾数据处理过程
  • 视频渲染器构建过程
  • 音频数据到Buffer过程
  • AudioPlayer在AwesomePlayer运行过程
  • 音视频同步
  • 音视频输出
  • 一张图看音视频输出

一张图回顾数据处理过程

这里写图片描述

视频渲染器构建过程

这里写图片描述

在构造时,new AweSomeEvent时,就开始把AwesomePlayer把onVideoEvent注入进去。

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

以上代码最会调用initRenderer_l函数

这里写图片描述

从上面代码来看:AwesomeRemoteRenderer的本质由OMX::createRenderer会先建立一个hardware renderer就是:mVideoRenderer =
new AwesomeNativeWindowRenderer(mNativeWindow, rotationDegrees);若失败,则建立new AwesomeLocalRenderer(mNativeWindow, format);
接下来看下:

这里写图片描述
这里写图片描述

而另一个AwesomeLocalRenderer在构造时new SoftwareRenderer(nativeWindow)

这里写图片描述

AwesomeLocalRender的本质上是由OMX:createRenderer,createRenderer会建立一个渲染器。如果video decoder是software component,则建立一个AwesomeLocalRenderer作为mVideoRenderer
AwesomeLocalRenderer的constructor会呼叫本身的init函数,其所做的事和OMX::createRenderer一模一样。可以理解为把read的数据显示在渲染器中。
渲染器渲染出画面后,我们可能会想,MediaExtractor把音视频进行分开,那音频呢?谁来让他们保持同步的呢?

音频数据到Buffer过程

无论是音频也好,还是视频,都是bufferdata,音频或视频总有一个来维持时间线的流。举个例子:我们看过双簧,一个人说话,一个人演示动作,动作快了不行,话说快,动作跟不上也不行。中间在联系台词时,自然有一些停顿或暗号。在OpenCore中,设置了一个主clock,而audio和video就分别以此作为输出的依据。而在Stagefright中,audio的输出是透过callback函式来驱动,video则根据audio的timestamp来做同步。在这之前,我们得了解下音频相关playback过程:
Stagefright框架中,audio的部分是交由AudioPlayer来处理,它是在AwesomePlayer::play_l中被建立的。贴一段以前分析过的代码:只不过当时没有向AudioPlayer方向向下看

这里写图片描述
这里写图片描述

创建AudioPlayer

这里写图片描述

再接着看下startAudioPlayer_l函数,

这里写图片描述

接下来看下音频mAudioPlayer->start(true)的操作,上面的过程都是在AwesomePlayer中,接下来变到AudioPlayer.cpp类中:

这里写图片描述
这里写图片描述

这里首先要介绍一下mAudioSink ,当mAudioSink不为NULL的时候,AudioPlayer会将其传入构造函数。
而且AudioPlayer中的播放操作都会依考mAudioSink来完成。
此处mAudioSink是从MediaPlayerService注册而来的AudioOut对象。具体代码在MediaPlayerservice中

这里写图片描述

间接地调用到stagefrightplayer->setAudioSink,最终到awesomeplayer中,如下:

这里写图片描述

而构造AudioPlayer时用到的就是mAudioSink成员,因此后面分析传入的mAudioSink的操作时,记住实际的对象为AudioOut对象,在MediaPlayerService定义。
本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52560012

AudioPlayer在AwesomePlayer运行过程

下面看AudioPlayer构造函数

这里写图片描述

主要是进行初始化,并将传入的mAudioSink存在成员mAudioSink中
再回到上面的start函数中
总结如下:

  • 调用mSource->read 启动解码,解码第一帧相当于启动了解码循环
  • 获取音频参数:采样率、声道数、以及量化位数(这里只支持PCM_16_BIT)
  • 启动输出:这里若mAudioSink非空,则启动mAudioSink进行输出,否则构造一个AudioTrack进行音频输出,这里AudioTrack是比较底层的接口 AudioOut是AudioTrack的封装。
  • 在start方法中主要是调用mAudioSink进行工作,主要代码如下:

这里写图片描述

刚介绍过mAudioSink是AudioOut对象,看下实际的实现(代码在mediaplayerservice.cpp中)

首先mAudioSink->open 需要注意的是传入的参数中有个函数指针 AudioPlayer::AudioSinkCallback ,其主要作用就是audioout播放pcm的时候会定期调用此回调函数填充数据,具体实现如下

这里写图片描述

以上代码总结为:

  • 1、处理传入的参数,回调函数保存在mCallback中, cookie代表的是AudioPlayer对象指针类型,接下来是根据采样率声道数等计算 frameCount。
  • 2、构造AudioTrack对象,并且赋值给t
  • 3、将audiotrack对象存储在mTrack成员中
    当以上过程完成后,继续分析AudioPlayer.start函数时,最后都会实例化一个AudioTrack对象,然后获取帧大小,比特等信息,然后调用mAudioTrack.start,最后到达mediaplayerservice音频输出start函数。

这里写图片描述

调用mTrack->start,audiotrack启动后就会周期性的调用 回调函数从解码器获取数据.
本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52560012

音视频同步

回到我们前面的问题:音视频如何同步?通过fillBuffer,不断填充buffer。
代码如下:

这里写图片描述

以上代码总结为:当callback函数回调AudioPlayer读取解码后的数据时,AudioPlayer会取得两个时间戳:mPositionTimeMediaUs和mPositionTimeRealUs,mPositionTimeMediaUs是数据里面所持有的时间戳(timestamp);mPositionTimeRealUs则是播放此数据的实际时间(依据frame number及sample rate得出)。

这里写图片描述

以上代码总结为:

  • 在构造audioplayer的时候会执行mTimeSource = mAudioPlayer,
    即将AudioPlayer作为参考时钟,
  • 上述代码中成员变量mSeekTimeUs是由如下语句获得:CHECK(mVideoBuffer->meta_data()->findInt64(kKeyTime, &timeUs));
  • realTimeOffset = getRealTimeUsLocked() - mPositionTimeRealUs; 当显示画面是第一帧时,表示当前的audio的播放时间与第一帧video的时间差值
  • 其中变量是通过mAudioPlayer->getMediaTimeMapping( int64_t *realtime_us, int64_t *mediatime_us) {
    Mutex::Autolock autoLock(mLock)得到

这里写图片描述

二者的差值表示这一包pcm数据已经播放了多少。Stagefright中的video便依据从AudioPlayer得出来之两个时间戳的差值,作为播放的依据

音视频输出

最后回到本文开头的onVideoEvent方法中,

这里写图片描述

这样最终音视频数据通过渲染器就到Surface显示画面,就可看到视频和听到声音了。
本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52560012

一张图看音视频输出

这里写图片描述

第一时间获得博客更新提醒,以及更多android干货,源码分析,欢迎关注我的微信公众号,扫一扫下方二维码或者长按识别二维码,即可关注。

这里写图片描述

如果你觉得好,随手点赞,也是对笔者的肯定,也可以分享此公众号给你更多的人,原创不易

作者:hejjunlin 发表于2016/9/17 1:56:40 原文链接
阅读:24 评论:0 查看评论

[React Native]获取网络状态

$
0
0

使用React Native,可以使用NetInfo API获取手机当前的各个网络状态。

    componentWillMount() {
        NetInfo.fetch().done((status)=> {
            console.log('Status:'+status);
        });
    }

获取网络状态是异步的,上面使用了Promise机制。

Android端网络状态

请求网络信息需要先在应用的AndroidManifest.xml文件中添加如下权限字段,申请相关权限:

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

这里写图片描述

修改完成后,reaload代码是无效的,因为我们修改了Android原生的配置文件,需要重新执行react-native run-android命令。这个命令重新编译对应的Android项目安装包并安装到手机中。

Android可获取的状态比较多,上面的status可能有如下的值,直接把文档贴出来了:
+ NONE - 设备处于离线状态
+ BLUETOOTH - 蓝牙数据连接
+ DUMMY - 模拟数据连接
+ ETHERNET - 以太网数据连接
+ MOBILE - 移动网络数据连接
+ MOBILE_DUN - 拨号移动网络数据连接
+ MOBILE_HIPRI - 高优先级移动网络数据连接
+ MOBILE_MMS - 彩信移动网络数据连接
+ MOBILE_SUPL - 安全用户面定位(SUPL)数据连接
+ VPN - 虚拟网络连接。需要Android5.0以上
+ WIFI - WIFI数据连接
+ WIMAX - WiMAX数据连接
+ UNKNOWN - 未知数据连接

IOS端网络状态

  • none - 设备处于离线状态。
  • wifi - 设备处于联网状态且通过wifi链接,或者是一个iOS的模拟器。
  • cell - 设备是通过Edge、3G、WiMax或是LTE网络联网的。
  • unknown - 发生错误,网络状况不可知

监听网络改变事件

在获取了网络状态后,开发者还可以通过NetInfo API提供的监听器,监听网络状态改变事件。这样当手机网络状态改变时,React Native应用马上收到通知。

    componentWillMount() {
        NetInfo.fetch().done((status)=> {
            console.log('Status:' + status);
        });
        //监听网络状态改变
        NetInfo.addEventListener('change', this.handleConnectivityChange);

    }

    componentWillUnMount() {
        console.log("componentWillUnMount");
        NetInfo.removeEventListener('change', this.handleConnectivityChange);
    }

    handleConnectivityChange(status) {
        console.log('status change:' + status);
        //监听第一次改变后, 可以取消监听.或者在componentUnmount中取消监听
       // NetInfo.removeEventListener('change', this.handleConnectivityChange);
    }

判断是否有网络连接

NetInfo API 为开发者提供了isConnected函数用来判断当前手机是否有网络连接。

NetInfo.isConnected.fetch().done((isConnected) => {
  console.log('First, is ' + (isConnected ? 'online' : 'offline'));
});

isConnectionExpensive(仅Android端)

NetInfo API为开发者提供了 isConnectionExpensive函数用来判断当前网络连接是否付费的。如果当前连接是通过移动数据网络,或者通过基于移动数据网络所创建的wifi热点,都有可能被判定为计费的数据连接。目前这个函数只为Android平台提供。

NetInfo.isConnectionExpensive((isConnectionExpensive) => {
  console.log('Connection is ' + (isConnectionExpensive ? 'Expensive' : 'Not Expensive'));
});

更多精彩请关注微信公众账号likeDev
这里写图片描述

作者:yulianlin 发表于2016/9/19 16:33:49 原文链接
阅读:176 评论:0 查看评论

E:安桌层及文件系统层的PRINTf输出原理

$
0
0


/device/console操控台原理分析,通过调用此操控台来输出信息,同时这儿涉及到/device/console调用TTY,然后TTY调用低层串口的分析 安桌LOG输出原理)

LINUX内核源码版本:linux-3.0.86  

 

/dev/console即控制台,是与操作系统交互的设备,系统将一些调试信息直接输出到控制台上,是TTY设备的一个子集

 

Tty:teltypewriters  Teletypes简称电传打印机:终端是一种字符型设备,它有多种类型,通常使用tty来简称各种类型的终端设备ConsoleTTY设备的一种。Console调用到最低层就是TTY设备驱动。

TTY CONSOLE UART关系图(由我的平台有4路串口,要分析到USER空间/dev/console最后是通过那一路口输出的,注意和内核空间的printkconsole操控台输出端口是否一致,分析原理。由前面几节分析可知printk输出是由uboot传入的参数来确定那一路串口输出的的。Console=ttySAC0,115200n80)

分析代码前根据网络资料得出的一张图:

 

自己分析代码后得到的图:

 

 

红色部分是分析了所有代码后得出的结论:

下面过程很杂乱,到现在还是没有分析清楚,只能是明白了个大概,因为结构体太多,没交繁复杂。现在还是乱。只能再次分析一下流程(只针对/dev/console的写过程。我们要知道用户空间的console是支持输入输出的。Kernel空音的console只支持输出信息。这是很重要的区别。)。

/dev/console

  1. 设备打开。得到tty_struct结构体,并且赋值在file中一个private_data中。同时由于

    struct tty_driver *console_driver = console_device(&index);得来是由uboot传入的参数来决定的。因此这儿/dev/console输出0串口来决定。由其它节部分的参数解析部分得知。

    struct tty_driver *console_driver = console_device(&index)->console_drivers(内核层register_console注册函数时一个指针链表)->driver = c->device(c, index);

  2. 写操作//把数据写入file文件中的private_data指向的tty_struct中的一xmit变量(这儿有好层转换),同时打开中断。产生中断条件。

    Write->[ld->ops->write=n_tty_write]->[tty->ops=driver->ops]=[tty_operations uart_ops]=[.write= uart_write,]

     

    3.中断发送://中断的注册是在open函数中执行的。这儿自动过来执行的。

    ret = request_irq(ourport->rx_irq, s3c24xx_serial_rx_chars, 0,

      s3c24xx_serial_portname(port), ourport);---->

    s3c24xx_serial_tx_chars->wr_regb(port, S3C2410_UTXH, xmit->buf[xmit->tail]);发送数据

     

    //下面是上面结论分析过程。

     

    /dev/console字符设备注册流程分析:

    #define fs_initcall(fn)__define_initcall("5",fn,5)

    chr_dev_init->tty_init->MKDEV(TTYAUX_MAJOR, 1)->console_fops操作函数

    static const struct file_operationsconsole_fops = {

    .llseek= no_llseek,

    .read= tty_read,

    .write= redirected_tty_write,

    .poll= tty_poll,

    .unlocked_ioctl= tty_ioctl,

    .compat_ioctl= tty_compat_ioctl,

    .open= tty_open,

    .release= tty_release,

    .fasync= tty_fasync,

    };

    完成了对设备的注册,然后是打开设备和读写设备了,这个部分应该是用户空间来完成的。我们不去看相关代码,只从通用的打开读写通用操作方法来作分析。Open write read这三个函数由用户空间来调用。当用户空间调打开读写函数时会调用上面注册的驱动的操作函数对应的函数。所以接下来分析Open write read

    Open:tty_open

    struct tty_driver *console_driver = console_device(&index)->console_drivers(内核层register_console注册函数时一个指针链表)->driver = c->device(c, index);

    retval = tty_alloc_file(filp);

    struct tty_driver *console_driver = console_device(&index);

  • tty = tty_init_dev(driver, index, 0);//这个函数里去构建LDISC结构体了,叫做线规程/线路规程line discipline

     

    /*

    //ldisc构建过程:

    tty_init_dev(driver, index, 0);//tty_driver  0  0

    initialize_tty_struct(tty, driver, idx);//tty_struct tty_driver 0

    tty_ldisc_init(tty);

    Ld->ops=tty_ldiscs[disc]=tty_ldiscs[0]

    /*

     

    ty_ldiscs怎么得来的是关键:

    start_kernel->console_init()->/* Setup the default TTY line discipline. */

    tty_ldisc_begin();->/* Setup the default TTY line discipline. */

    (void) tty_register_ldisc(N_TTY, &tty_ldisc_N_TTY);->->

    N_TTY=0

    struct tty_ldisc_ops tty_ldisc_N_TTY = {

    .magic           = TTY_LDISC_MAGIC,

    .name            = "n_tty",

    .open            = n_tty_open,

    .close           = n_tty_close,

    .flush_buffer    = n_tty_flush_buffer,

    .chars_in_buffer = n_tty_chars_in_buffer,

    .read            = n_tty_read,

    .write           = n_tty_write,

    .ioctl           = n_tty_ioctl,

    .set_termios     = n_tty_set_termios,

    .poll            = n_tty_poll,

    .receive_buf     = n_tty_receive_buf,

    .write_wakeup    = n_tty_write_wakeup

    };

    tty_ldiscs[disc] = new_ldisc;

    tty_ldiscs[0] = tty_ldisc_N_TTY ;等于上面TTY设备

    通过上面分析可知

    Ld->ops=tty_ldiscs[disc]=tty_ldiscs[0]=tty_ldisc_N_TTY

     

     

    */

    tty->ldisc = ld;

    tty_add_file(tty, filp);

    struct tty_file_private *priv = file->private_dat=tty_struct;因此通过file文件中的private_data来操作tty_sruct。这个结构体时里面包含tty_driver tty->ldisc多个变量。

     

     

    */

    tty_add_file(tty, filp);

    上面代码完成通过文件的struct tty_file_private *priv = file->private_data变量来保存tty_struct(同时TTY结构体包含tty_drivers)驱动变量。

     

    我们代码的console_drivers如下:

    static struct console s3c24xx_serial_console = {

    .name= S3C24XX_SERIAL_NAME,

    .device=uart_console_device,

    .flags= CON_PRINTBUFFER,

    .index= -1,

    .write= s3c24xx_serial_console_write,

    .setup= s3c24xx_serial_console_setup,

    .data= &s3c24xx_uart_drv,

    };

    struct tty_driver *uart_console_device(struct console *co, int *index)

    {

    struct uart_driver *p = co->data;

    *index = co->index;//0通过UBOOT传入参数等到0

    returnp->tty_driver;

    }

    static struct uart_driver s3c24xx_uart_drv = {

    .owner= THIS_MODULE,

    .driver_name= "s3c2410_serial",

    .nr= CONFIG_SERIAL_SAMSUNG_UARTS,

    #ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE_SWITCH

    .cons= NULL,

    #else

    .cons= S3C24XX_SERIAL_CONSOLE,

    #endif

    .dev_name= S3C24XX_SERIAL_NAME,

    .major= S3C24XX_SERIAL_MAJOR,

    .minor= S3C24XX_SERIAL_MINOR,

    };

    p->tty_drivers3c24xx_uart_drv结构体的成员,但在上面数组的初始化中并没有初始化此值,因此可以肯定是在在其它地方初始化的tty_driver的。

    下面来分析tty_driver的初始化流程:

    s3c24xx_serial_modinit->uart_register_driver(&s3c24xx_uart_drv)->:

    struct tty_driver *normal;

    drv->tty_driver = normal;

    tty_set_operations(normal, &uart_ops); //driver->ops = op;

    /*

    static const struct tty_operations uart_ops = {

    .open= uart_open,

    .close= uart_close,

    .write= uart_write,

    .put_char= uart_put_char,

    .flush_chars= uart_flush_chars,

    .write_room= uart_write_room,

    .chars_in_buffer= uart_chars_in_buffer,

    .flush_buffer= uart_flush_buffer,

    .ioctl= uart_ioctl,

    .throttle= uart_throttle,

    .unthrottle= uart_unthrottle,

    .send_xchar= uart_send_xchar,

    .set_termios= uart_set_termios,

    .set_ldisc= uart_set_ldisc,

    .stop= uart_stop,

    .start= uart_start,

    .hangup= uart_hangup,

    .break_ctl= uart_break_ctl,

    .wait_until_sent= uart_wait_until_sent,

    #ifdef CONFIG_PROC_FS

    .proc_fops= &uart_proc_fops,

    #endif

    .tiocmget= uart_tiocmget,

    .tiocmset= uart_tiocmset,

    .get_icount= uart_get_icount,

    #ifdef CONFIG_CONSOLE_POLL

    .poll_init= uart_poll_init,

    .poll_get_char= uart_poll_get_char,

    .poll_put_char= uart_poll_put_char,

    #endif

    };

    tty->ops = driver->ops;

    struct tty_driver *driver;

    struct tty_driver *console_driver = console_device(&index);

    tty->ops=driver->ops->console_drivers->driver = c->device(c, index)->

     tty_operations uart_ops=tty_operations uart_ops;--->tty->ops=driver->ops=tty_operations uart_ops

     

    */

    通过上面代码分析可知:用操作/dev/console写函数时

    .write= redirected_tty_write,

    static ssize_t tty_write(struct file *file, const char __user *buf,

    size_t count, loff_t *ppos)

    struct tty_struct *tty = file_tty(file);//包含tty_driver结构体。

    ld = tty_ldisc_ref_wait(tty);

    ld->ops->write//////因此找到这个函数才是我们的根本,看是如何实现的。????????????????

    通过前面分析知:

    Ld->ops=tty_ldiscs[disc]=tty_ldiscs[0]=tty_ldisc_N_TTY

    因此ld->ops->write=n_tty_write//tty_ldisc_N_TTY中的函数完成线程规程检查

    最后还是调用tty->ops->write(tty, b, nr);来输出数据。规则检查部分不能把数据输出的串口

    综上:对于/dev/console设备的写函数的执行流程如下:

    Write->[ld->ops->write=n_tty_write]->[tty->ops=driver->ops]=[tty_operations uart_ops]=[.write= uart_write,]

    static int uart_write(struct tty_struct *tty,

    const unsigned char *buf, int count)

    __uart_start(tty);

    port->ops->start_tx(port);//ops= s3c24xx_serial_ops;

    static struct uart_ops s3c24xx_serial_ops = {

    .pm= s3c24xx_serial_pm,

    .tx_empty= s3c24xx_serial_tx_empty,

    .get_mctrl= s3c24xx_serial_get_mctrl,

    .set_mctrl= s3c24xx_serial_set_mctrl,

    .stop_tx= s3c24xx_serial_stop_tx,

    .start_tx= s3c24xx_serial_start_tx,

    .stop_rx= s3c24xx_serial_stop_rx,

    .enable_ms= s3c24xx_serial_enable_ms,

    .break_ctl= s3c24xx_serial_break_ctl,

    .startup= s3c24xx_serial_startup,

    .shutdown= s3c24xx_serial_shutdown,

    .set_termios= s3c24xx_serial_set_termios,

    .type= s3c24xx_serial_type,

    .release_port= s3c24xx_serial_release_port,

    .request_port= s3c24xx_serial_request_port,

    .config_port= s3c24xx_serial_config_port,

    .verify_port= s3c24xx_serial_verify_port,

    .wake_peer= s3c24xx_serial_wake_peer,

    };

    s3c24xx_serial_start_tx//这个函数是打开中断  我们/dev/console应该是通过中断来把数据发送出去的。数据存在struct circ_buf xmit结构体中。这个函数只是把数据缓存在变量中和打开串口,发送数据是在中断中进行的。tty->ops->open(tty, filp);====s3c24xx_serial_startup打开中断ret = request_irq(ourport->rx_irq, s3c24xx_serial_rx_chars, 0,

      s3c24xx_serial_portname(port), ourport);注册串口发送函数。

    static irqreturn_t

    static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id)

    struct s3c24xx_uart_port *ourport = id;

    struct circ_buf *xmit = &port->state->xmit;//这个是在s3c24xx_serial_start_tx中去指定的。

    /*

    ret = request_irq(ourport->rx_irq, s3c24xx_serial_rx_chars, 0,

      s3c24xx_serial_portname(port), ourport);*/

    上面中断函数的id/dev/consoletty_drvier是同一个变量。所以在触发中断发送时能正确的发送数据。wr_regb(port, S3C2410_UTXH, xmit->buf[xmit->tail]);

     

     

     

     

    /dev/tty字符设备注册流程分析:

    #define fs_initcall(fn)__define_initcall("5",fn,5)

    chr_dev_init->tty_init->MKDEV(TTYAUX_MAJOR, 0)->tty_fops

    上面只是注册了一个tty设备。Tty其实是一多个的。最后是tty_register_driver-for (i = 0; i < driver->num; i++) {

    d = tty_register_device(driver, i, NULL);-device_create(tty_class, device, dev, NULL, name);

    上面完成多个设备的注册tty设备的注册,这儿主要是串串的。所有的tty一字符输输入输出设备都可以用tty_register_driver来注册。可以注册多个。上面/dev/console只是利用了其中的一类来解决问题。Tty设备是可以单独来解决问题的。用tty_register_driver注册。但我们分析的串口部分是用的tty_init来注册设备。然后通过打开函数来与tty_structtty_drvier关联解决问题。大致分析了代码发/dev/conosle/  /dev/tty逻辑差不多。细节就不去分析了。可以明确的是对这两个设备的输入输出都是由uboot传入参数来决是那一个口的。前一个用于系统信息调试 ,后一个应该是作其它功能。对于这设备当作一般设备来理解。只是加入很多中间层,所以分析起来比较麻烦。暂不去细究。分析了好几天还是乱。不是清晰的逻辑。

     

    static const struct file_operations tty_fops = {

    .llseek= no_llseek,

    .read= tty_read,

    .write= tty_write,

    .poll= tty_poll,

    .unlocked_ioctl= tty_ioctl,

    .compat_ioctl= tty_compat_ioctl,

    .open= tty_open,

    .release= tty_release,

    .fasync= tty_fasync,

    };

    兴趣交流群抠抠: 461283592

     

作者:YACHL882828 发表于2016/9/19 16:37:18 原文链接
阅读:136 评论:0 查看评论

CoreText(五):省略号

$
0
0

直接附代码:

#import "MyView.h"
#import <CoreText/CoreText.h>

// 行距
const CGFloat kGlobalLineLeading = 5.0;

// 在15字体下,比值小于这个计算出来的高度会导致emoji显示不全
const CGFloat kPerLineRatio = 1.4;

@interface MyView()


@property (nonatomic ,assign) CGFloat textHeight;

@end


@implementation MyView
- (instancetype)initWithFrame:(CGRect)frame{
    self = [super initWithFrame:frame];
    if (self) {
        self.text = @"我自横刀向天笑,去留肝胆两昆仑。--谭嗣同同学你好啊。This is my first CoreText demo,how are you ?I love three things,the sun,the moon,and you.the sun for the day,the moon for the night,and you forever.��������������去年今日此门中,人面桃花相映红。人面不知何处去,桃花依旧笑春风。��������������少年不知愁滋味,爱上层楼,爱上层楼,为赋新词强说愁。56321363464.而今识尽愁滋味,欲说还休,欲说还休,却道天凉好个秋。123456,7890,56321267895434。缺月挂疏桐,漏断人初静。谁见幽人独往来,缥缈孤鸿影。惊起却回头,有恨无人省。捡尽寒枝不肯栖,寂寞沙洲冷。";
        self.font = [UIFont systemFontOfSize:15];
    }
    return self;
}
/**
 *  高度 = 每行的固定高度 * 行数
 */
+ (CGFloat)textHeightWithText:(NSString *)aText width:(CGFloat)aWidth font:(UIFont *)aFont{
    NSMutableAttributedString *content = [[NSMutableAttributedString alloc] initWithString:aText];
    // 给字符串设置字体行距等样式
    [self addGlobalAttributeWithContent:content font:aFont];
    CTFramesetterRef framesetterRef = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)content);
    // 粗略的高度,该高度不准,仅供参考
    CGSize suggestSize = CTFramesetterSuggestFrameSizeWithConstraints(framesetterRef, CFRangeMake(0, content.length), NULL, CGSizeMake(aWidth, MAXFLOAT), NULL);
    NSLog(@"suggestHeight = %f",suggestSize.height);

    CGMutablePathRef pathRef = CGPathCreateMutable();
    CGPathAddRect(pathRef, NULL, CGRectMake(0, 0, aWidth, suggestSize.height));

    CTFrameRef frameRef = CTFramesetterCreateFrame(framesetterRef, CFRangeMake(0, content.length), pathRef, NULL);

    CFArrayRef lines = CTFrameGetLines(frameRef);
    CFIndex lineCount = CFArrayGetCount(lines);

    NSLog(@"行数 = %ld",lineCount);
    // 总高度 = 行数*每行的高度,其中每行的高度为指定的值,不同字体大小不一样
    CGFloat accurateHeight = lineCount * (aFont.pointSize * kPerLineRatio);

    CGFloat height = accurateHeight;

    CFRelease(pathRef);
    CFRelease(frameRef);

    return height;
}
#pragma mark - 工具方法
#pragma mark 给字符串添加全局属性,比如行距,字体大小,默认颜色
+ (void)addGlobalAttributeWithContent:(NSMutableAttributedString *)aContent font:(UIFont *)aFont
{
    CGFloat lineLeading = kGlobalLineLeading; // 行间距

    const CFIndex kNumberOfSettings = 2;
    //设置段落格式
    CTParagraphStyleSetting lineBreakStyle;
    CTLineBreakMode lineBreakMode = kCTLineBreakByWordWrapping;
    lineBreakStyle.spec = kCTParagraphStyleSpecifierLineBreakMode;
    lineBreakStyle.valueSize = sizeof(CTLineBreakMode);
    lineBreakStyle.value = &lineBreakMode;

    //设置行距
    CTParagraphStyleSetting lineSpaceStyle;
    CTParagraphStyleSpecifier spec;
    spec = kCTParagraphStyleSpecifierLineSpacingAdjustment;
    lineSpaceStyle.spec = spec;
    lineSpaceStyle.valueSize = sizeof(CGFloat);
    lineSpaceStyle.value = &lineLeading;

    // 结构体数组
    CTParagraphStyleSetting theSettings[kNumberOfSettings] = {
        lineBreakStyle,
        lineSpaceStyle,
    };
    CTParagraphStyleRef theParagraphRef = CTParagraphStyleCreate(theSettings, kNumberOfSettings);

    // 将设置的行距应用于整段文字
    [aContent addAttribute:NSParagraphStyleAttributeName value:(__bridge id)(theParagraphRef) range:NSMakeRange(0, aContent.length)];

    CFStringRef fontName = (__bridge CFStringRef)aFont.fontName;
    CTFontRef fontRef = CTFontCreateWithName(fontName, aFont.pointSize, NULL);
    // 将字体大小应用于整段文字
    [aContent addAttribute:NSFontAttributeName value:(__bridge id)fontRef range:NSMakeRange(0, aContent.length)];

    // 给整段文字添加默认颜色
    [aContent addAttribute:NSForegroundColorAttributeName value:[UIColor blackColor] range:NSMakeRange(0, aContent.length)];
    // 内存管理
    CFRelease(theParagraphRef);
    CFRelease(fontRef);
}
#pragma mark - 一行一行绘制,行高确定,行与行之间对齐
#pragma mark - 一行一行绘制,行高确定,高度不够时加上省略号
- (void)drawRectWithLineByLineAlignmentAndEllipses{
    // 1.创建需要绘制的文字
    NSMutableAttributedString *attributed = [[NSMutableAttributedString alloc] initWithString:self.text];

    // 2.设置行距等样式
    [[self class] addGlobalAttributeWithContent:attributed font:self.font];

    self.textHeight = [[self class] textHeightWithText:self.text width:CGRectGetWidth(self.bounds) font:self.font];

    // 3.创建绘制区域,path的高度对绘制有直接影响,如果高度不够,则计算出来的CTLine的数量会少一行或者少多行
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathAddRect(path, NULL, CGRectMake(0, 0, CGRectGetWidth(self.bounds), self.textHeight*2));

    // 4.根据NSAttributedString生成CTFramesetterRef
    CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attributed);
    CTFrameRef ctFrame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, attributed.length), path, NULL);

    // 重置高度
    CGFloat realHeight = self.textHeight;
    // 绘制全部文本需要的高度大于实际高度则调整,并加上省略号
    if (realHeight > CGRectGetHeight(self.frame)){
        realHeight = CGRectGetHeight(self.frame);
    }
    NSLog(@"realHeight = %f",realHeight);
    // 获取上下文
    CGContextRef contextRef = UIGraphicsGetCurrentContext();

    // 转换坐标系
    CGContextSetTextMatrix(contextRef, CGAffineTransformIdentity);
    CGContextTranslateCTM(contextRef, 0, realHeight); // 这里跟着调整
    CGContextScaleCTM(contextRef, 1.0, -1.0);

    // 这里可调整可不调整
    CGPathAddRect(path, NULL, CGRectMake(0, 0, CGRectGetWidth(self.bounds), realHeight));

    // 一行一行绘制
    CFArrayRef lines = CTFrameGetLines(ctFrame);
    CFIndex lineCount = CFArrayGetCount(lines);
    CGPoint lineOrigins[lineCount];
    // 把ctFrame里每一行的初始坐标写到数组里,注意CoreText的坐标是左下角为原点
    CTFrameGetLineOrigins(ctFrame, CFRangeMake(0, 0), lineOrigins);
    CGFloat frameY = 0;
    for (CFIndex i = 0; i < lineCount; i++){
        // 遍历每一行CTLine
        CTLineRef line = CFArrayGetValueAtIndex(lines, i);
        CGFloat lineAscent;
        CGFloat lineDescent;
        CGFloat lineLeading; // 行距
        // 该函数除了会设置好ascent,descent,leading之外,还会返回这行的宽度
        CTLineGetTypographicBounds(line, &lineAscent, &lineDescent, &lineLeading);
        //CoreText的origin的Y值是在baseLine处,而不是下方的descent。
        CGPoint lineOrigin = lineOrigins[i];
        //行高
        CGFloat lineHeight = self.font.pointSize * kPerLineRatio;
        //self.font.descender为负值
        frameY = realHeight - (i + 1)*lineHeight - self.font.descender;
        NSLog(@"frameY = %f",frameY);
        lineOrigin.y = frameY;
        //调整坐标
        CGContextSetTextPosition(contextRef, lineOrigin.x, lineOrigin.y);
        if (frameY + self.font.descender > lineHeight){
            CTLineDraw(line, contextRef);
        }else{
            NSLog(@"最后一行");
            // 最后一行,加上省略号
            static NSString* const kEllipsesCharacter = @"\u2026";
            CFRange lastLineRange = CTLineGetStringRange(line);
            // 一个emoji表情占用两个长度单位
            NSLog(@"range.location = %ld,range.length = %ld,总长度 = %ld",lastLineRange.location,lastLineRange.length,attributed.length);
            if (lastLineRange.location + lastLineRange.length < (CFIndex)attributed.length){
                // 这一行放不下所有的字符(下一行还有字符),则把此行后面的回车、空格符去掉后,再把最后一个字符替换成省略号
                CTLineTruncationType truncationType = kCTLineTruncationEnd;
                NSUInteger truncationAttributePosition = lastLineRange.location + lastLineRange.length - 1;

                // 拿到最后一个字符的属性字典
                NSDictionary *tokenAttributes = [attributed attributesAtIndex:truncationAttributePosition
                                                               effectiveRange:NULL];
                // 给省略号字符设置字体大小、颜色等属性
                NSAttributedString *tokenString = [[NSAttributedString alloc] initWithString:kEllipsesCharacter
                                                                                  attributes:tokenAttributes];

                // 用省略号单独创建一个CTLine,下面在截断重新生成CTLine的时候会用到
                CTLineRef truncationToken = CTLineCreateWithAttributedString((__bridge CFAttributedStringRef)tokenString);

                // 把这一行的属性字符串复制一份,如果要把省略号放到中间或其他位置,只需指定复制的长度即可
                NSUInteger copyLength = lastLineRange.length;

                NSMutableAttributedString *truncationString = [[attributed attributedSubstringFromRange:NSMakeRange(lastLineRange.location, copyLength)] mutableCopy];

                if (lastLineRange.length > 0)
                {
                    // Remove any whitespace at the end of the line.
                    unichar lastCharacter = [[truncationString string] characterAtIndex:copyLength - 1];

                    // 如果复制字符串的最后一个字符是换行、空格符,则删掉
                    if ([[NSCharacterSet whitespaceAndNewlineCharacterSet] characterIsMember:lastCharacter])
                    {
                        [truncationString deleteCharactersInRange:NSMakeRange(copyLength - 1, 1)];
                    }
                }

                // 拼接省略号到复制字符串的最后
                [truncationString appendAttributedString:tokenString];

                // 把新的字符串创建成CTLine
                CTLineRef truncationLine = CTLineCreateWithAttributedString((__bridge CFAttributedStringRef)truncationString);

                // 创建一个截断的CTLine,该方法不能少,具体作用还有待研究
                CTLineRef truncatedLine = CTLineCreateTruncatedLine(truncationLine, self.frame.size.width, truncationType, truncationToken);

                if (!truncatedLine)
                {
                    // If the line is not as wide as the truncationToken, truncatedLine is NULL
                    truncatedLine = CFRetain(truncationToken);
                }

                CFRelease(truncationLine);
                CFRelease(truncationToken);

                CTLineDraw(truncatedLine, contextRef);
                CFRelease(truncatedLine);
            } else{
                // 这一行刚好是最后一行,且最后一行的字符可以完全绘制出来
                CTLineDraw(line, contextRef);
            }
            // 跳出循环,避免绘制剩下的多余的CTLine
            break;
        }
    }
    CFRelease(path);
    CFRelease(framesetter);
    CFRelease(ctFrame);
}



- (void)drawRect:(CGRect)rect
{
    [self drawRectWithLineByLineAlignmentAndEllipses];
}
@end

调用:

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    // Do any additional setup after loading the view, typically from a nib.
    MyView *view = [[MyView alloc]initWithFrame:CGRectMake(0, 20, self.view.width, 100)];
    view.backgroundColor = [UIColor redColor];
    view.text = @"我自横刀向天笑,去留肝胆两昆仑。--谭嗣同同学你好啊。This is my first CoreText demo,how are you ?I love three things,the sun,the moon,and you.the sun for the day,the moon for the night,and you forever.��������������去年今日此门中,人面桃花相映红。人面不知何处去,桃花依旧笑春风。��������������少年不知愁滋味,爱上层楼,爱上层楼,为赋新词强说愁。56321363464.而今识尽愁滋味,欲说还休,欲说还休,却道天凉好个秋。123456,7890,56321267895434。缺月挂疏桐,漏断人初静。谁见幽人独往来,缥缈孤鸿影。惊起却回头,有恨无人省。捡尽寒枝不肯栖,寂寞沙洲冷。";
    view.font = [UIFont systemFontOfSize:15];
    [self.view addSubview:view];
}

结果:
这里写图片描述

参考:
CoreText使用教程(四)

作者:xiaoxiaobukuang 发表于2016/9/19 16:41:55 原文链接
阅读:141 评论:0 查看评论

仿知乎日报第十篇:从网络加载首页数据,为首页设置数据

$
0
0

一.这一篇我们要从网络为首页加载数据,解析数据,并为各个组件设置数据。我们先来看看HomePage的代码,逻辑后面分析。代码看起虽然挺多的,逻辑却没有几步。

public class HomeBasePage extends BasePage {
 
    private Gson                mGson;
    private HomeDataBean        mHomeData;
    private List<HomeLunboData>     mLunboDatas       = new ArrayList<HomeDataBean.HomeLunboData>();
    private List<HomeListViewData>  mListViewDatas    = newArrayList<HomeDataBean.HomeListViewData>();
    private LunboAdapter        mLunboAdapter;
    private int                     selectedPosition;
    private ListViewAdapter         mListViewAdapter;
    private BitmapUtils             mBitmapUtils;
 
    public HomeBasePage(MainActivity mainActivity) {
       super(mainActivity);
       // TODO自动生成的构造函数存根
    }
 
    @Override
    public void initData(String themeDailyNumber) {
//     BitmapUtils类专门用来异步从网络加载图片
       if (mBitmapUtils == null) {
           mBitmapUtils = new BitmapUtils(mainActivity);
           mBitmapUtils.configDefaultBitmapConfig(Config.ARGB_4444);
       }
//     首页显示设置按钮
       ibSetting.setVisibility(View.VISIBLE);
//     设置首页标题
       tvTitle.setText("首页");
//     从网络中加载数据
       loadData();
 
    }
 
    @Override
    protected void initListener() {
       vpLunboPic.setOnPageChangeListener(new OnPageChangeListener() {
 
           @Override
           public void onPageSelected(int position) {
//            轮播图一切换,拿到该页面的position,传给成员变量selectedPosition
              selectedPosition = position;
//            为轮播图设置标题并把该页面对应的点从灰色变成白色
              setTextAndSelectPoint();
           }
 
           @Override
           public void onPageScrolled(int arg0, float arg1, int arg2) {
              // TODO自动生成的方法存根
 
           }
 
           @Override
           public void onPageScrollStateChanged(int arg0) {
              // TODO自动生成的方法存根
 
           }
       });
//     ListView的item一点击,带着该item的文章id去ArticleActivity
       lvNews.setOnItemClickListener(new OnItemClickListener() {
 
           @Override
           public void onItemClick(AdapterView<?> parent, View view,
                  int position, long id) {
//            因为ListView有个头布局,而头布局的position为0,头布局不是文章item,所以position != 0
              if (position != 0) {
                  String url = MyContants.BASEARTICLESTRING + mHomeData.stories.get(position-1).id;
                 
                  Intent intent = new Intent(mainActivity,ArticleActivity.class);
                  intent.putExtra("articleUrl", url);
                  mainActivity.startActivity(intent);
              }
             
           }
       });
       super.initListener();
 
    }
 
    private void loadData() {
 
       mLunboAdapter = new LunboAdapter();
//     为轮播图的ViewPager设置Adapter
       vpLunboPic.setAdapter(mLunboAdapter);
 
       mListViewAdapter = new ListViewAdapter();
//     为ListView设置Adapter
       lvNews.setAdapter(mListViewAdapter);
//     先从SharedPreference里面拿json数据
       String jsonCache = SpTools.getString(mainActivity,
              MyContants.HOMELATEST, "");
//     如果数据存在,直接去解析Json数据
       if (!TextUtils.isEmpty(jsonCache)) {
           // System.out.println(jsonCache);
           parseData(jsonCache);
       }
      
       HttpUtils httpUtils = new HttpUtils();
//     用HttpUtils异步从网络获取数据
//     第一个参数:get方式获取数据
//     第二个参数:url地址
//     第三个参数:回调对象,获取数据成功或获取数据失败后调用
       httpUtils.send(HttpMethod.GET, MyContants.HOMELATEST,
              new RequestCallBack<String>() {
 
                  @Override
                  public void onSuccess(ResponseInfo<String> responseInfo) {
//                   获取数据成功后,拿到json数据
                     String homeJsonData = responseInfo.result;
//                   这里做一个缓存,把json数据保存到SharedPreference里面
                     SpTools.putString(mainActivity,MyContants.HOMELATEST,
                            homeJsonData);
//                   System.out.println("Data" +homeJsonData);
                     if (!TextUtils.isEmpty(homeJsonData) ) {
                         parseData(homeJsonData);
                     }
                    
 
                  }
 
                  @Override
                  public void onFailure(HttpException error, String msg) {
                     // TODO自动生成的方法存根
 
                  }
              });
    }
   
 
    private void parseData(String homeJsonData) {
//     创建Gson对象,这个对象只要有一个就可以了,所以只有为空的时候才创建
       if (mGson == null) {
           mGson = new Gson();
       }
//     用Gson解析数据
       mHomeData = mGson.fromJson(homeJsonData, HomeDataBean.class);
       //System.out.println(mHomeData.stories.get(0).images.get(0));
//     处理数据
       processData();
    }
 
    private void processData() {
       // 1.给ViewPager数据
       setLunboData();
 
       // 2.初始化点
       initLunboPoints();
 
       // 3.设置标题及点的选中
       setTextAndSelectPoint();
 
       // 4.为ListView设置数据
 
       setListViewData();
 
    }
 
    private void setListViewData() {
//     为ListView设置数据
      
       mListViewDatas = mHomeData.stories;
 
    }
 
    private class ListViewAdapter extends BaseAdapter {
 
       @Override
       public int getCount() {
           return mListViewDatas.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, ViewGroupparent) {
           ViewHolder viewHolder;
           if (convertView == null) {
//            加载ListView的item的布局
              convertView = View.inflate(mainActivity, R.layout.list_item,
                     null);
              viewHolder = new ViewHolder();
//            拿到item里面的各个组件
              viewHolder.textView = (TextView) convertView
                     .findViewById(R.id.tv_list_item_title);
              viewHolder.imageView = (ImageView) convertView
                     .findViewById(R.id.iv_list_item_image);
              convertView.setTag(viewHolder);
           } else {
              viewHolder = (ViewHolder) convertView.getTag();
           }
//         为item里面的TextView组件设置标题
           viewHolder.textView.setText(mListViewDatas.get(position).title);
//         为item里面的ImageView组件设置图片,还是用BitmapUtils异步加载
           String listImageUrl = mListViewDatas.get(position).images.get(0);
           if (!TextUtils.isEmpty(listImageUrl)) {
              mBitmapUtils.display(viewHolder.imageView, listImageUrl);
           } else {
              viewHolder.imageView.setVisibility(View.GONE);
           }
 
           return convertView;
       }
 
    }
 
    private class ViewHolder {
       TextView   textView;
       ImageView  imageView;
    }
 
    private voidsetTextAndSelectPoint() {
//     设置轮播图的标题
       tvLunboTitle.setText(mHomeData.top_stories.get(selectedPosition).title);
//     遍历,轮播图的setOnPageChangeListener的onPageChange方法中拿到了当前的页面的position,
//     并把它传给selectedPosition,如果i为selectedPosition,则把点设为白点
       for (int i = 0; i < mLunboDatas.size(); i++) {
           llLunboPoints.getChildAt(i).setEnabled(i == selectedPosition);
 
       }
    }
 
    private void initLunboPoints() {
//     先移除轮播图下面所有的点
       llLunboPoints.removeAllViews();
//     遍历轮播图的数量,即有多少轮播图,就创建几个点
       for (int i = 0; i < mLunboDatas.size(); i++) {
 
           View view = new View(mainActivity);
//         为View设置背景,背景为一个选择器,state_enabled为true的时候为白点,为false的时候为灰点
           view.setBackgroundResource(R.drawable.selector_lunbo_points);
//         默认都设为灰色点
           view.setEnabled(false);
          
//         为点View创建LayoutParams,里面传入的参数是px
//         所以我们创建了一个工具类DensityUtil的dip2px()方法将density单位转为像素单位px
 
           LayoutParams layoutParams = new LayoutParams(DensityUtil.dip2px(
                  mainActivity, 5), DensityUtil.dip2px(mainActivity, 5));
//         为点View设置左边边距
           layoutParams.leftMargin = DensityUtil.dip2px(mainActivity, 5);
//         为点View设置LayoutParams
           view.setLayoutParams(layoutParams);
//         把点加进LinearLayout
           llLunboPoints.addView(view);
 
       }
    }
 
    private class LunboAdapter extends PagerAdapter {
 
       @Override
       public int getCount() {
           return mLunboDatas.size();
       }
 
       @Override
       public boolean isViewFromObject(View arg0, Object arg1) {
           // TODO自动生成的方法存根
           return arg0 == arg1;
       }
 
       @Override
       public void destroyItem(ViewGroup container, int position, Objectobject) {
           container.removeView((View) object);
       }
 
       @Override
       public Object instantiateItem(ViewGroup container, int position) {
//         轮播图的每一页页面都是一个ImageView
           ImageView imageView = new ImageView(mainActivity);
//         ImageView上面的图片x轴,y轴上都拉伸
           imageView.setScaleType(ScaleType.FIT_XY);
          
//         用BitmapUtills从网上异步加载图片,并放在ImageView容器中
//         第一个参数为容器
//         第二个参数为url
           mBitmapUtils.display(imageView,
                  mHomeData.top_stories.get(position).image);
          
//         轮播图的ImageView一点击,带着该轮播图页面的文章id去ArticleActivity
           imageView.setOnClickListener(new OnClickListener() {
             
              @Override
              public void onClick(View v) {
                  String url = MyContants.BASEARTICLESTRING + mHomeData.top_stories.get(vpLunboPic.getCurrentItem()).id;
                 
                  Intent intent = new Intent(mainActivity,ArticleActivity.class);
                  intent.putExtra("articleUrl", url);
                  mainActivity.startActivity(intent);
              }
           });
 
           container.addView(imageView);
          
           return imageView;
       }
    }
 
    private void setLunboData() {
//     拿到轮播图的数据
       mLunboDatas = mHomeData.top_stories;
//     更新轮播图的展示
       mLunboAdapter.notifyDataSetChanged();
    }
 
}
 


二.我们现在来分析逻辑

 

过程上面已经有了,无非就是设置一些能设置的控件,需要从网络拿的数据的过程就是,先从本地拿,本地没有,再去网络拿,然后就解析数据,然后用解析后的数据为轮播图及ListView设置数据,轮播图和ListView都用Adapter,过程也大同小异,前面都讲过了。还是不会的话看代码的注释吧。

三.这里我们专门来讲一下怎样用Gson来解析json数据

1)Gson包复制到libs目录下面

 

2.从网上拿到json数据,放到HiJson软件下面


3.在项目中专门创建一个bean包,专门放各种Bean类


4.以首页数据为例,我们从网上拿到的数据是这样的

 

5.接下去放到Hijson里面格式化


6.根据结构创建HomeDataBean

public class HomeDataBean {
    public String               date;
    public List<HomeListViewData>   stories;
    public List<HomeLunboData>      top_stories;
//  ListView的数据
    public class HomeListViewData {
       public String ga_prefix;
       public String id;
       public List<String> images;
       public String title;
       public String type;
       public String multipic;
 
    }
//  轮播图的数据
 
    public class HomeLunboData {
       public String ga_prefix;
       public String id;
       public String image;
       public String title;
       public String type;
    }
 
}


7.创建Gson对象,调用Gson对象的fromJson方法解析

if (mGson == null) {
           mGson = new Gson();
       }
mHomeData = mGson.fromJson(homeJsonData, HomeDataBean.class);


作者:baoyunmian 发表于2016/9/19 16:49:12 原文链接
阅读:136 评论:0 查看评论

Android中ClassLoader源码解析之真的是你认为的ClassLoader

$
0
0

1.前言

首先,阅读本文章之前,需要了解java中的ClassLoader的基本原理,包括java中的三级ClassLoader机制以及ClassLoader的委托机制,否则下面的内容会不知道在讲什么。虽然Android中的ClassLoader也是遵循其委托机制,但是他没有遵循java的三级ClassLoader机制,而是自己造了一个,修改了java系统的代码,如果将两者混淆的话,在Android中使用ClassLoader的时候,你可能会遇到想不通的问题。(因为作者曾经就踩过坑。。。。。。)

首先,我们看下面一段代码,在Application的onCreate()中添加如下代码:
PathClassLoader classLoader = (PathClassLoader) getApplicationContext().getClassLoader();
Log.d("mytest", "classLoader : " + classLoader + "\n" +
            "parent : " + classLoader.getParent() + "\n" +
            "grandParent : " + classLoader.getParent().getParent() + "\n" +
            "system classloader : " + ClassLoader.getSystemClassLoader() + "\n" +
            "system parent : " + ClassLoader.getSystemClassLoader().getParent());

代码的执行结果,打印内容如下:
 classLoader : dalvik.system.PathClassLoader[dexPath=/data/app/com.gavin.demo2application-1.apk,libraryPath=/data/app-lib/com.gavin.demo2application-1]
 parent : java.lang.BootClassLoader@41099128
 grandParent : null
 system classloader : dalvik.system.PathClassLoader[dexPath=.,libraryPath=null]
 system parent : java.lang.BootClassLoader@41099128

看到上面的打印的内容,我们了解到在Android的项目中使用的ClassLoader是其自定义的PathClassLoader,最重要的一点是打印的dexPath,这个决定了在项目代码中要加载的类的位置(后面详细讲解)。
第二点奇怪的地方就是它的parent是 BootClassLoader,这个又是什么东西,后面详细讲解。
第三点调用ClassLoader.getSystemClassLoader()返回的是PathClassLoader,并且dexPath为. ,我们了解的java中的ClassLoader.getSystemClassLoader()返回的是加载classpath里面的class的ClassLoader,也就是java中的第三级ClassLoader,它是调用sun.misc.Launcher的getClassLoader()方法获取的,详细解析请自行查阅。
第四点它的parent也是BootClassLoader,看来这个必须要分析一下下,毕竟出镜率这么高。

2.Context.getClassLoader()返回的是PathClassLoader

首先,Android中可以使用的CLassLoader有PathClassLoader和DexClassLoader,PathClassLoader只能加载dex文件,我们安装apk之后会在/data/dalvik-cache目录下生产一个名为data@app@com.hujiang.xxx-1.apk@classes.dex的 ODEX 文件,而PathClassLoader要加载apk的时候会到这个文件夹下找对应的dex文件。(ODEX文件就是经过优化的dex文件,详细自行查阅),同时也是我们自己编写的项目中使用的ClassLoader。而DexClassLoader可以加载apk,dex,jar文件,就是被用来实现动态加载机制,加载一个外部的apk文件,实现完全解耦的模块式开发,现在的开源框架有DL(使用代理的方式,其实加载的不是插件中的类)和DroinPlugin(hook掉AMS和PMS实现);现在比较火的热修改也是和其有关系,比如AndFix(它是在运行时将java方法修改成native方法,然后修改调用这个方法的指针,指向修复的方法),nuwa(也就是qq空间实现基于dex分包,修改CLassLoader中的dexElements中的dex顺序实现)以及最新的美团的Robust(基于Android Studio的instance run的原理,为每个类创建代理类)。
关于上面所提的动态加载框架,热修复框架等等都会在后续的文章中进行分析。

上面说了那么多,现在开始分析PathClassLoader和DexCLassLoader的源码实现,他们都是继承BaseDexClassLoader,所有的实现都疯转在了这个类里面,先来看看PathClassLoader和DexClassLoader的源码.
PathClassLoader的代码:
public class PathClassLoader extends BaseDexClassLoader {

37    public PathClassLoader(String dexPath, ClassLoader parent) {
38        super(dexPath, null, null, parent);
39    }
40

63    public PathClassLoader(String dexPath, String libraryPath,
64            ClassLoader parent) {
65        super(dexPath, null, libraryPath, parent);
66    }
67}
68

DexClassLoader源码如下:
public class DexClassLoader extends BaseDexClassLoader {

55    public DexClassLoader(String dexPath, String optimizedDirectory,
56            String libraryPath, ClassLoader parent) {
57        super(dexPath, new File(optimizedDirectory), libraryPath, parent);
58    }
59}
可以看出他们仅仅是重写了构造函数,所以所有的实现都是在BaseDexClassLoader里面。
参数:dexPath:要加载的apk或者jar文件的路径,optimizedDirectory:从apk中解析出dex文件存储的路径,libraryPath:apk文件中类要使用的c/c++代码,parent:父装载器,也就是真正loadclass的装载器。

下面重点来了,分析BaseDexClassLoader的源码,首先构造函数如下:
public BaseDexClassLoader(String dexPath, File optimizedDirectory,
            String libraryPath, ClassLoader parent) {
        super(parent);
        this.pathList = new DexPathList(this, dexPath, libraryPath, optimizedDirectory);
    }
super()走的是ClassLoader的设置parent的ClassLoader的方式,重点是下面的PathList,他存储的是dex的集合,因为apk是可以dex分包,它里面含有一个DexElement的集合,每一个Element就对应一个dex文件。

DexPathList的构造函数的核心代码如下:
this.dexElements = makeDexElements(splitDexPath(dexPath), optimizedDirectory,
                                           suppressedExceptions);
makeDexElements()就是解析dex文件成对应的DexElement,代码如下:
private static Element[] makeDexElements(ArrayList<File> files, File optimizedDirectory,
                                            ArrayList<IOException> suppressedExceptions) {
        ArrayList<Element> elements = new ArrayList<Element>();
209        /*
210         * Open all files and load the (direct or contained) dex files
211         * up front.
212         */
213        for (File file : files) {//遍历所有的dex文件
214            File zip = null;
215            DexFile dex = null;//这是核心的类,处理将dex文件转化成对应的DexFile对象
216            String name = file.getName();
217
218            if (name.endsWith(DEX_SUFFIX)) {//.dex结尾(针对PathClassLoader处理)
219                // Raw dex file (not inside a zip/jar).
220                try {
221                    dex = loadDexFile(file, optimizedDirectory);//核心方法,内部是调用的DexFile的loadDex()方法
222                } catch (IOException ex) {
223                    System.logE("Unable to load dex file: " + file, ex);
224                }
225            } else if (name.endsWith(APK_SUFFIX) || name.endsWith(JAR_SUFFIX)
226                    || name.endsWith(ZIP_SUFFIX)) {//.dex .jar .apk 结尾 (针对DexClassLoader处理)
227                zip = file;
228
229                try {
230                    dex = loadDexFile(file, optimizedDirectory);
231                } catch (IOException suppressed) {
232                    /*
233                     * IOException might get thrown "legitimately" by the DexFile constructor if the
234                     * zip file turns out to be resource-only (that is, no classes.dex file in it).
235                     * Let dex == null and hang on to the exception to add to the tea-leaves for
236                     * when findClass returns null.
237                     */
238                    suppressedExceptions.add(suppressed);
239                }
240            } else if (file.isDirectory()) {
241                // We support directories for looking up resources.
242                // This is only useful for running libcore tests.
243                elements.add(new Element(file, true, null, null));//创建Element对象
244            } else {
245                System.logW("Unknown file type for: " + file);
246            }
247
248            if ((zip != null) || (dex != null)) {
249                elements.add(new Element(file, false, zip, dex));
250            }
251        }
252
253        return elements.toArray(new Element[elements.size()]);
254    }
上面的代码是遍历所有的dex文件,然后调用的DexFile的loadDex()方法,内部就是创建一个DexFile对象,这个构造函数中会调用openDexFile()解析dex文件,这是一个native()方法,使用c代码实现的,这里就不分析了,如果想要学习,推荐一篇博客:DexClassLoader源码解析
关于DexFile,AndFix就是直接使用DexFile直接加载的dex文件,而没有使用DexClassLoader,有兴趣可以查看AndFix的源码。

3.Context的getClassLoader()为什么返回是PathClassLoader,探索其中奥秘

我们都知道getApplicationContext()的返回的实现类是ContextImpl,下面来看看ContextImpl的getClassLoader()的代码实现:
public ClassLoader getClassLoader() {
        return mPackageInfo != null ?
                mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader();
}
我们看到如果mPackageInfo不为null,就调用它的getClassLoader()方法,否则调用ClassLoader.getSystemClassLoader(),这里我们看到了ClassLoader的getSystemClassLoader()方法,但是这里还不是重点,重点是mPackageInfo这个对象,这是什么呢,它是一个LoadedAPK对象。它又是什么呢?
官方文档说明如下:
Local state maintained about a currently loaded .apk.
LoaderAPK对象是apk在内存中的表示。通过这个LoaderApk对象可以拿到apk中代码和资源,甚至里面Activity和Service等信息。
那么它又是哪里创建的,又是什么时候创建的呢,如果你了解Activity的启动过程,你就明白了(如果想了解,推荐老罗的文章),这里就不赘述了。在ActivityThread里面有一个mPackages的map类型的成员变量,根据键值(packageName)存储对应的LoadedApk对象。启动Activity的时候要调用LoadedApk的getClassLoader(),来加载对应的Activity class文件,然后通过反射创建这个activity的实例;那么获取这个对象,会先去mPackages中去查找有没有缓存,如果没有就创建一个新的LoadedAPK对象。
下面代码截取自ActivityThread中启动Activity的过程中创建LoadedApk的代码:
public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai,
        CompatibilityInfo compatInfo) {
    return getPackageInfo(ai, compatInfo, null, false, true, false);
}
private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo,
        ClassLoader baseLoader, boolean securityViolation, boolean includeCode,
        boolean registerPackage) {
        // 获取userid信息
    final boolean differentUser = (UserHandle.myUserId() != UserHandle.getUserId(aInfo.uid));
    synchronized (mResourcesManager) {
    // 尝试获取缓存信息
        WeakReference<LoadedApk> ref;
        if (differentUser) {
            // Caching not supported across users
            ref = null;
        } else if (includeCode) {
            ref = mPackages.get(aInfo.packageName);
        } else {
            ref = mResourcePackages.get(aInfo.packageName);
        }

        LoadedApk packageInfo = ref != null ? ref.get() : null;
        if (packageInfo == null || (packageInfo.mResources != null
                && !packageInfo.mResources.getAssets().isUpToDate())) {
                // 缓存没有命中,直接new
            packageInfo =
                new LoadedApk(this, aInfo, compatInfo, baseLoader,
                        securityViolation, includeCode &&
                        (aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0, registerPackage);

        // 省略。。更新缓存
        return packageInfo;
    }
}
下面看上面使用到的LoadedApk的构造函数,其实LoadedApk还有一个构造函数,在ContextImpl创建自己的实例的同时创建其LoadedApk的成员变量的时候使用了。
108    public LoadedApk(ActivityThread activityThread, ApplicationInfo aInfo,
109            CompatibilityInfo compatInfo,
110            ActivityThread mainThread, ClassLoader baseLoader,
111            boolean securityViolation, boolean includeCode) {
<span style="white-space:pre">	</span>   .......(省略)
126
127        if (mAppDir == null) {
128            if (ActivityThread.mSystemContext == null) {//这个context很重要,一个ActivityThread只有这一个,是静态全局的
129                ActivityThread.mSystemContext =
130                    ContextImpl.createSystemContext(mainThread);
131                ActivityThread.mSystemContext.getResources().updateConfiguration(
132                         mainThread.getConfiguration(),
133                         mainThread.getDisplayMetricsLocked(compatInfo, false),
134                         compatInfo);
135                //Slog.i(TAG, "Created system resources "
136                //        + mSystemContext.getResources() + ": "
137                //        + mSystemContext.getResources().getConfiguration());
138            }
139            mClassLoader = ActivityThread.mSystemContext.getClassLoader();//这个ClassLoader就是最后返回的那个ClassLoader
140            mResources = ActivityThread.mSystemContext.getResources();
141        }
142    }
143
看到这里,我们只要最终这个CLassLoader的来源是从Context那里后去的,也就是ActivityThread的mSystemContext里面的ClassLoader,我们来看一下这个mSystemContext的创建过程,代码如下:
1458    static ContextImpl createSystemContext(ActivityThread mainThread) {
1459        ContextImpl context = new ContextImpl();
1460        context.init(Resources.getSystem(), mainThread);//这个init操作也没有创建他里面LoadedApk成员变量
1461        return context;
1462    }
所以最终调用的代码,就是最开始的ContextImpl的getClassLoader()方法,并且mPackageInfo(LoadedAPK对象)为null,所以最终调用的是ClassLoader.getSystemClassLoader(),所以最终结论就是系统ClassLoader是通过ClassLoader.getSystemClassLoader()创建。

4.揭开ClassLoader.getSystemClassLoader()在Android中的神秘面纱


其代码如下:
public static ClassLoader getSystemClassLoader() {
     return SystemClassLoader.loader;
}
static private class SystemClassLoader {
        public static ClassLoader loader = ClassLoader.createSystemClassLoader();
}
    private static ClassLoader createSystemClassLoader() {
        String classPath = System.getProperty("java.class.path", ".");
        return new PathClassLoader(classPath, BootClassLoader.getInstance());
    }
对于最有一个核心方法createSystemClassLoader(),官方说明如下:
Create the system class loader. Note this is NOT the bootstrap class
loader (which is managed by the VM). We use a null value for the parent
to indicate that the bootstrap loader is our parent.
创建系统的ClassLoader。注释:这不是bootstrap ClassLoader(被虚拟机管理的ClassLoader)。我们使用null作为我们系统ClassLoader的parent来表明bootstrap就是我们的系统ClassLoader的parent。这里也就是充分说明了Android系统不是使用的java原生的bootstrap来加载,而是使用自己的创建的套机制。取代bootstrap的是用null(bootstrap不是一个ClassLoader对象,所以他的子级ClassLoader调用getParent()返回的是null),而取代java中第二级的ClassLoader使用Android中创建的最基层的BootClassLoader(也就是上面的PathClassLoader的parent)。
这个BootClassLoader是单例的,所以全局只有一个,我们也可以得出,系统所有执行装载类的操作,都会执行到这个对象。代码如下:
public BootClassLoader() {
     super(null, true);//他的parent为null(模拟它的parent是bootstrap)
}

还有我们看到上面PathClassLoader构造函数中传递的第一个参数classPath,这个就是我们之前打印出来的dexPath。为什么系统的ClassLoader.getSystemClassLoader()返回的PathClassLoader 的dexPath指向的是当前apk的安装路径;但是我们自己创建的返回的PathClassLoader的dexPath却是.  我们发现是由上面的System.getProperty("java.class.path",".");决定的,看到get操作,相对的也就会有set操作,那么这个值是什么时候设置的呢。这我们就要追溯到Android framwork中System中的initSystemProperty()方法中,调用VMRuntime.getRuntime().classPath()的值,这个值应该就是当前apk的安装路径。
代码如下: 路径:/libcore/luni/src/main/java/java/lang/System.java(4.0.4)
private static void initSystemProperties() {
        VMRuntime runtime = VMRuntime.getRuntime();
        Properties p = new Properties();

        String projectUrl = "http://www.android.com/";
        String projectName = "The Android Project";

        p.put("java.boot.class.path", runtime.bootClassPath());
        p.put("java.class.path", runtime.classPath());
}
但是,为什么我们自己调用,获取这个值就是. 我的猜想就是 系统创建完对应的ClassLoader之后,就将这个值修改成了.(当然这仅仅是我个人的猜想,希望了解的大神能帮我解答一下,因为我实在是找不到原因,困惑好久了)。


5.总结

1.Android系统最顶级的ClassLoader是BootClassLoader(替代java中第二级的ext ClassLoader),而用来加载系统的类是使用的以这儿BootClassLoader为parent的PathClassLoader(替代java中第三级加载classpath的ClassLoader)。

2.Android系统的PathClassLoader的dexPath(要加载类的路径),指向当前apk安装的路径,然后使用DexFile来解析对应的dex文件,装载里面的class

3.DexClassLoader,主要用于加载外部插件,也就是可以直接加载一个apk文件,现在的插件化动态加载机制,热修复等都要使用到它的特性,当然直接使用里面的DexFile直接加载dex文件也是可以(AndFix就是这样做的)。

4.自己遇到的坑:我之前在学习动态化的时候,看完原理之后,自己创建一个DexClassLoader ,它的parent我设置的是系统PathClassLoader(也就是context.getClassLoader()),但是load外部apk中的类的时候,报错:当前apk的安装路径下(也就是这个apk文件对应生成的ODEX文件)找不到对应的类,也就是ClassNotFoundException,但是自己不明白为什么我用DexClassLoader加载的外部apk,但是它却到系统中去寻找。现在明白了因为我传递的是PathClassLoader的dexPath是指向系统的apk的路径的,自然会到那里去找。但是如果传递的是ClassLoader.getSystemClassLoader(),因为dexPath是. ,是Directory,就不会创建DexFile,也就不会走DexFile的loadDexFile()方法,而是直接调用它的parent也就是BootClassLoader的findClass()来装载当前类。

文章终于写完了,鄙人愚钝,水平有限,文章难免有错,欢迎指出。










作者:u010014658 发表于2016/9/19 16:54:52 原文链接
阅读:191 评论:0 查看评论

java Lock和Condition的用法

$
0
0

前面我分享了Synchronized的使用,当一个线程访问一个对象的Synchronized方法或者代码块的时候,就持有了锁,除非执行完或者遇到异常(发生异常JVM虚拟机会自动释放锁),才能释放锁,但是如果在执行代码块里sleep了或者有一些耗时很久的操作,那么锁就一直不释放,其他线程就会一直等待下去,Lock可以不让其他线程一直无限等待下去,另外一种情况,当有多个线程读写文件的时候,读和写会发生冲突,写和写会发生冲突,读和读按理应该不会发生冲突,但是如果用Synchronized的话,读和读也会发生冲突,ReadWriteLock可以解决这个问题,有一个点需要强调下,Synchronized是java内置语言,Lock不是,当一个线程执行完Synchronized修饰的方法或代码块之后,JVM会自动释放锁,但是Lock不会,必须手动执行lock.unLock()方法来释放锁,否则锁就永远不会得到释放。
1 Lock.lock,代码如下:

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class LockTest {
    public static void main(String args[]) {
        LockObject lo = new LockObject();
        MyThread t1 = new MyThread(lo);
        MyThread t2 = new MyThread(lo);
        Thread ta = new Thread(t1,"A");
        Thread tb = new Thread(t2,"B");
        ta.start();
        tb.start();

    }
}

class LockObject {
    Lock lock = new ReentrantLock();

    public void LockFuc() {
        lock.lock();
        try {
            System.out.println(Thread.currentThread().getName() + "得到了锁");

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
            System.out.println(Thread.currentThread().getName() + "释放了锁");
        }
    }
}

class MyThread implements Runnable{
    LockObject lo= null;
    public MyThread(LockObject lo){
        this.lo = lo;
    }
    @Override
    public void run() {
        // TODO Auto-generated method stub
        lo.LockFuc();
    }


}

开始调用了lock.lock得到锁,然后同步代码放到try catch中,在finally里执行lock.unlock释放锁,执行结果如下:
A得到了锁
A释放了锁
B得到了锁
B释放了锁

2 lock.tryLock(),代码如下:

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class LockTest {
    public static void main(String args[]) {
        LockObject lo = new LockObject();
        MyThread t1 = new MyThread(lo);
        MyThread t2 = new MyThread(lo);
        Thread ta = new Thread(t1, "A");
        Thread tb = new Thread(t2, "B");
        ta.start();
        tb.start();

    }
}

class LockObject {
    Lock lock = new ReentrantLock();

    public void LockFuc() {
        if (lock.tryLock()) {
            try {
                System.out.println(Thread.currentThread().getName() + "得到了锁");

            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
                System.out.println(Thread.currentThread().getName() + "释放了锁");
            }
        }else{
            System.out.println(Thread.currentThread().getName() + "没有得到锁");
        }
    }
}

class MyThread implements Runnable {
    LockObject lo = null;

    public MyThread(LockObject lo) {
        this.lo = lo;
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        lo.LockFuc();
    }

}

tryLock()方法是有返回值的,它表示用来尝试获取锁,如果获取成功,则返回true,如果获取失败(即锁已被其他线程获取),则返回false,也就说这个方法无论如何都会立即返回。在拿不到锁时不会一直在那等待,执行结果如下:
A得到了锁
B没有得到锁
A释放了锁

3 tryLock(long time, TimeUnit unit)方法和tryLock()方法是类似的,只不过区别在于这个方法在拿不到锁时会等待一定的时间,在时间期限之内如果还拿不到锁,就返回false。如果如果一开始拿到锁或者在等待期间内拿到了锁,则返回true。

4 lockInterruptibly(),代码如下:

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class LockTest {
    public static void main(String args[]) {
        LockObject lo = new LockObject();
        MyThread t1 = new MyThread(lo);
        MyThread t2 = new MyThread(lo);
        Thread ta = new Thread(t1, "A");
        Thread tb = new Thread(t2, "B");

        ta.start();

        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        tb.start();
        tb.interrupt();

    }
}

class LockObject {
    Lock lock = new ReentrantLock();

    public void LockFuc() throws InterruptedException {
        lock.lockInterruptibly();
            try {
                System.out.println(Thread.currentThread().getName() + "得到了锁");
                while(true){
                    ;
                }

            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
                System.out.println(Thread.currentThread().getName() + "释放了锁");
            }
    }
}

class MyThread implements Runnable {
    LockObject lo = null;

    public MyThread(LockObject lo) {
        this.lo = lo;
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        try{
            lo.LockFuc();
        }catch(InterruptedException e){
            System.out.println(Thread.currentThread().getName()+"被中断");
        }

    }

}

lock.lockInterruptibly()想获取某个锁时,假若此时线程A获取到了锁,而线程B只有在等待,那么对线程B调用threadB.interrupt()方法能够中断线程B的等待过程。执行结果如下:
A得到了锁
B被中断

下面来看读写锁ReadWriteLock,可以实现读和读不冲突:

import java.util.concurrent.locks.ReentrantReadWriteLock;

public class LockTest {
    public static void main(String args[]) {
        LockObject lo = new LockObject();
        MyThread t1 = new MyThread(lo);
        MyThread t2 = new MyThread(lo);
        Thread ta = new Thread(t1, "A");
        Thread tb = new Thread(t2, "B");

        ta.start();
        tb.start();

    }
}

class LockObject {
    ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

    public void LockFuc(){
        lock.readLock().lock();
            try {
                System.out.println(Thread.currentThread().getName() + "得到了锁");
                for(int i=0;i<10;i++){
                    System.out.println(Thread.currentThread().getName() + "正在进行读操作" + i);
                }

            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.readLock().unlock();
                System.out.println(Thread.currentThread().getName() + "释放了锁");
            }
    }
}

class MyThread implements Runnable {
    LockObject lo = null;

    public MyThread(LockObject lo) {
        this.lo = lo;
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
            lo.LockFuc();


    }

}

执行结果如下:
A得到了锁
B得到了锁
A正在进行读操作0
B正在进行读操作0
A正在进行读操作1
B正在进行读操作1
A正在进行读操作2
B正在进行读操作2
A正在进行读操作3
B正在进行读操作3
B正在进行读操作4
B正在进行读操作5
B正在进行读操作6
B正在进行读操作7
B正在进行读操作8
B正在进行读操作9
A正在进行读操作4
A正在进行读操作5
B释放了锁
A正在进行读操作6
A正在进行读操作7
A正在进行读操作8
A正在进行读操作9
A释放了锁
可以看到读和读并不冲突,但是如果有Synchronized修饰的话,会发现是冲突的。

接下来说下Condition:Condition是在java 1.5中才出现的,它用来替代传统的Object的wait()、notify()实现线程间的协作,相比使用Object的wait()、notify(),使用Condition1的await()、signal()这种方式实现线程间协作更加安全和高效。因此通常来说比较推荐使用Condition,Conditon中的await()对应Object的wait();Condition中的signal()对应Object的notify();Condition中的signalAll()对应Object的notifyAll(),接下来看个例子,重写生产者与消费者:

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/*
 * 生产者与消费者问题
 */
public class ProduceConsume {
    public static void main(String[] args) {
        SyncStack ss = new SyncStack();
        Produce pd = new Produce(ss);
        Consume cs = new Consume(ss);
        Thread t1 = new Thread(pd);
        Thread t2 = new Thread(cs);
        t1.start();
        t2.start();
    }
}

/*
 * 馒头实体类
 */
class ManTou {
    private int id;

    public ManTou(int id) {
        this.id = id;
    }

    public int getId() {
        return this.id;
    }

    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return "ManTou " + getId();
    }
}

/*
 * 馒头框类
 */
class SyncStack {
    Lock lock = new ReentrantLock();
    Condition full = lock.newCondition();
    Condition empty = lock.newCondition();
    int index = 0;
    ManTou[] mtArray = new ManTou[6];

    public void push(ManTou mt) {
        lock.lock();
        try {
            while (index == mtArray.length) {
                try {
                    full.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            empty.signal();
            mtArray[index] = mt;
            index++;
            System.out.println("生产了" + mt);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void pop() {
        lock.lock();
        try {
            while (index == 0) {
                try {
                    empty.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            full.signal();
            index--;
            System.out.println("消费了" + mtArray[index]); 
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}

/*
 * 生产者
 */
class Produce implements Runnable {
    SyncStack ss = null;

    public Produce(SyncStack ss) {
        this.ss = ss;
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        for (int i = 0; i < 20; i++) {
            ManTou mt = new ManTou(i);
            if (ss != null) {
                ss.push(mt);
            }
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}

/*
 * 消费者
 */
class Consume implements Runnable {
    SyncStack ss = null;

    public Consume(SyncStack ss) {
        this.ss = ss;
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        for (int i = 0; i < 20; i++) {
            if (ss != null) {
                ss.pop();
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}

跟之前Object的wait()、notify()的写法很类似。
以上如有问题,欢迎指正,谢谢。

作者:swjtufq 发表于2016/9/19 17:19:46 原文链接
阅读:150 评论:0 查看评论

芒果iOS开发之Swift教程02-Swift基本数据结构

$
0
0

【主要内容】

1.整型

2.浮点型

3.类型安全和类型推断

4.数值型字面量

5.数值类型转换

6. 类型别名


一、整型

1.1 整数和整型

编程语言中的整型是用来表示我们自然界中的整数。先来补习一下小学的知识,整数的概念:正整数、零、负整数统称为整数。

按照有无符号可以分为两种:1.有符号整数(正整数、零、负整数)2.无符号整数(正整数和零)

Swift提供了8,16,32和64位的有符号和无符号的整数类型,比如:8位无符号整数类型是UInt8,32位有符号整数类型Int32


1.2 整型表示的范围

Swift中提供了minmax属性来访问不同整数类型的最小值和最大值,比如8位无符号/有符号整型表示的最大值最小值,如图:



1.3 Int类型

一般写代码的时候不需要专门制定整数类型的长度,Swift还提供了一个特殊的整数类型:Int,Int类型的长度取决于当前平台的系统位数:

在32位平台上Int类型就是32位,和Int32长度相同。

在64位平台上Int类型就是64位,和Int64长度相同。


1.4 UInt类型

UInt类型和Int类型一样,它的长度取决于当前平台的系统位数。

注意:

开发中尽量不要使用UInt类型,最好使用Int,即使你要储存的值就是非负数。可以提高代码的复用性,避免不同类型数字之间的转换,并且匹配数字的类型推断。


二、浮点型

浮点数就是带有小数点的数字,比如常见的:3.14,0.618。Swift中提供了两种浮点数类型:

Float 表示32位浮点数。精度要求不高的话使用此类型。

Double表示64位浮点数。当需要储存很大或者很高精度的浮点数的时候才使用此类型。

注意:

Double的精度可以达到小数点后至少15位数字,而Float只有小数点后6位。一般来说Float类型足够用。


三、类型安全和类型推断

Swift是一种类型安全(type safe)的语言。类型安全的语言可以让你清除的知道代码要处理的值的类型。如果你的代码需要传递的参数是String类型,那么你绝对不可能不小心船进入一个非String类型。

由于Swift是类型安全的,所以它会在编译你的代码时进行类型检查(typy checks),并把不匹配的类型标记为错误,这样可以让你尽早的发现问题并修复。

当你要处理不同类型的值时,类型检查可以帮你避免错误。但是你不必每次声明常量、变量的时候都显示制定类型,如果没有制定类型,Swift会使用类型推断(type inference)帮你选择合适的类型。原理就是检查你的赋值即可。

虽然有类型推断,但是Swift很少需要自己显示声明类型,这些工作交给编译器去做就可以了。

 例如:

声明一个没有标注类型的常量money,赋值998,Swift可以推断出常量的类型是Int,从下图控制台的信息可以得到论证:


如果你给变量、常量赋值了一个浮点类型的值,Swift会默认推断为Double类型,如图:



四、数值型字面量

一个整数的字面量可以被写成以下几种形式:

一个十进制数,没有前缀

一个二进制数,前缀是0b

一个八进制数,前缀是0o

一个十六进制数,前缀是0x

比如:



浮点型字面量可以是十进制(没有前缀)或者十六进制(前缀是0x)。小数点两边必须有至少一个十进制数字(或者是十六进制的数字)。十进制浮点数也可以有一个可选的指数(exponent),通过大写或者小写的e来制定,十六进制浮点型数必须有一个指数,通过大写或者小写的p来指定。

如果一个十进制数的指数为exp,那这个数相当于基数和10^exp的乘积:

1.25e2 表示1.25 × 10^2,等于125.0。

1.25e-2表示1.25×10^-2,等于0.0125。

如果一个十六机制数的指数为exp,那这个数相当于基数和的2^exp的乘积:

0xFp2表示15×2^2,等于60.0.

0xFp-2表示15×2^-2,等于3.75。

下面的这些浮点字面量都等于十进制的12.1875:

let decimalDouble = 12.1875
let exponentDouble = 1.21875e1
let hexadecimalDouble = 0xC.3p0


数值类字面量可以包括额外的格式来增强可读性。整数和浮点数都可以添加额外的零并且包含下划线,并不会影响字面量:

let paddedDouble = 000123.456
let oneMillion = 1_000_000
let justOverOneMillion = 1_000_000.000_000_1

五、数值型类型转换

在开发的时候,如果没有明确说一定要声明无符号整型(要求优化性能、减少内存占用等),请使用系统默认的Int类型。因为系统默认整数类型的字面量默认的类型推断也是Int类型。

5.1 整数之间的转换

不同的整数类型存储的范围不同,可以通过max和min属性得到。Int类型可以存储的数值范围:-128~127,UInt类型存储的数值范围:0~255。如果超出了这个范围系统在编译的时候就会报错:

上边这两个错误就是说:你存储的值溢出了当前这个类型所表示的范围。

如果想要两个不同整数类型的值进行操作的时候,必须要转化成相同的类型:

let value1: UInt16 = 2_000
let value2: UInt8 = 1
let value3 = value1 + UInt16(value2)

value1是UInt16类型,value2是UInt8类型,需要先用SomeType(ofInitialValue)方法将value2转化为UInt16类型的数再进行运算。

5.2整数和浮点数转换

整数和浮点数的转换必须显式指定类型:

let integerValue = 7
let fValue = 3.14
let fNumber = Double(integerValue) + fValue
print("fNumber = \(fNumber)")

常量integerValue被转换成了Double类型,这样加号两边的数类型相同就可以进行运算。

浮点类型同样可以转换成整数类型:

let integerNum = Int(fValue)
print(integerNum)

当浮点类型转换为整数类型的时候,浮点类型会丢失精度,只保存浮点类型的整数位。上边integerNum输出的值为3。

注意:

数字类型的常量或变量进行运算,不同于数字字面量之间进行运算。数字字面量可以直接进行运算,比如3 + 0.1415,因为数字字面量本身没有确定的类型,但是数字类型常量、变量是会被编译器推断出具体类型的,只有类型相同才能进行运算。


六、类型别名

类型别名(type aliases)就是给现有的类型定义一个新的名字。跟OC里边的typedef是类似。在Swift中你可以使用typealias关键字来定义类型别名。平常在开发的时候偶尔也会用到但是不多。类型别名在苹果的Api里边大量的出现,特别是在一些地图类、音视频类等等的Api里边,经常会给现有类型起一个更有意义的别名。

比如:在GCD里边,如果想要某个线程延迟几秒执行,你得先定义一个延迟时间dispatch_time_t ,你点击进去查看Api就会发现其实它是UInt64类型:


下边自己定义一个类型别名:

typealias requestTimeOut = Int
var time:requestTimeOut = 10
time = 7
print(time)
print(requestTimeOut.max)

上边的定义了一个请求超时时间的类型别名,那么以前需要用到Int的地方就可以直接替换成requestTimeOut。


欢迎大家关注”芒果iOS“微信公众账号,芒果会经常为大家分享好的技术文章:




作者:CrazyZhang1990 发表于2016/9/19 17:58:29 原文链接
阅读:126 评论:0 查看评论

4AppBarLayout滑动原理

$
0
0

4AppBarLayout滑动原理

CoordinatorLayout的measure和layout里,其实介绍过一点AppBarLayout,这篇将重点讲解AppBarLayout的滑动原理以及behavior是如何影响onTouchEvent与onInterceptTouchEvent的。

基本原理

介绍AppBarLayout的mTotalScrollRange,mDownPreScrollRange,mDownScrollRange,滑动的基本概念
mTotalScrollRange内部可以滑动的view的高度(包括上下margin)总和

官方介绍

先来看看google的介绍
AppBarLayout is a vertical LinearLayout which implements many of the features of material designs app bar concept, namely scrolling gestures.

Children should provide their desired scrolling behavior through setScrollFlags(int) and the associated layout xml attribute: app:layout_scrollFlags.

This view depends heavily on being used as a direct child within a CoordinatorLayout. If you use AppBarLayout within a different ViewGroup, most of it’s functionality will not work.

AppBarLayout also requires a separate scrolling sibling in order to know when to scroll. The binding is done through the AppBarLayout.ScrollingViewBehavior behavior class, meaning that you should set your scrolling view’s behavior to be an instance of AppBarLayout.ScrollingViewBehavior. A string resource containing the full class name is available.

简单的整理下,AppBarLayout是一个vertical的LinearLayout,实现了很多material的概念,主要是跟滑动相关的。AppBarLayout的子view需要提供layout_scrollFlags参数。AppBarLayout和CoordinatorLayout强相关,一般作为CoordinatorLayout的子类,配套使用。
按我的理解,AppBarLayout内部有2种view,一种可滑出(屏幕),另一种不可滑出,根据app:layout_scrollFlags区分。一般上边放可滑出的下边放不可滑出的。

举个例子如下,内有个Toolbar、TextView,Toolbar写了app:layout_scrollFlags=”scroll”表示可滑动,Toolbar高200dp,TextView高100dp。Toolbar就是可滑出的,TextView就是不可滑出的。此时框高300(200+100),内容300,可滑动范围200

总高度300,可滑出部分高度200,剩下100不可滑出

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:background="?attr/colorPrimary"
            app:layout_scrollFlags="scroll"
            app:popupTheme="@style/AppTheme.PopupOverlay" />

        <TextView
            android:background="#ff0000"
            android:layout_width="match_parent"
            android:layout_height="100dp"></TextView>

    </android.support.design.widget.AppBarLayout>

效果如下所示

这个跟ScrollView有所不同,框的大小和内容大小一样,这样上滑的时候,底部必然会空出一部分(200),ScrollView的实现是通过修改scrollY,而AppBarLayout的实现是直接修改top和bottom的,其实就是把整个AppBarLayout内部的东西往上平移。

down事件

来看看上图的事件传递的顺序,先看down。简单来说,这个down事件被传递下来,一直无人处理,然后往上传到CoordinatorLayout被处理。但实际上CoordinatorLayout本身无法处理事件(他只是个壳),内部实际交由AppBarLayout的behavior处理。

总体分析

首先,down事件从CoordinatorLayout传到AppBarLayout再到TextView,没人处理,然后回传回来到AppBarLayout的onTouchEvent,不处理,再回传给CoordinatorLayout的onTouchEvent,这里主要看L10 performIntercept,type为TYPE_ON_TOUCH。

   @Override
    public boolean onTouchEvent(MotionEvent ev) {
        boolean handled = false;
        boolean cancelSuper = false;
        MotionEvent cancelEvent = null;

        final int action = MotionEventCompat.getActionMasked(ev);

        //此处会分发事件给behavior
        if (mBehaviorTouchView != null || (cancelSuper = performIntercept(ev, TYPE_ON_TOUCH))) {
            // Safe since performIntercept guarantees that
            // mBehaviorTouchView != null if it returns true
            final LayoutParams lp = (LayoutParams) mBehaviorTouchView.getLayoutParams();
            final Behavior b = lp.getBehavior();
            if (b != null) {
                handled = b.onTouchEvent(this, mBehaviorTouchView, ev);
            }
        }

        // Keep the super implementation correct
        if (mBehaviorTouchView == null) {
            handled |= super.onTouchEvent(ev);
        } else if (cancelSuper) {
            if (cancelEvent == null) {
                final long now = SystemClock.uptimeMillis();
                cancelEvent = MotionEvent.obtain(now, now,
                        MotionEvent.ACTION_CANCEL, 0.0f, 0.0f, 0);
            }
            super.onTouchEvent(cancelEvent);
        }

        if (!handled && action == MotionEvent.ACTION_DOWN) {

        }

        if (cancelEvent != null) {
            cancelEvent.recycle();
        }

        if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
            resetTouchBehaviors();
        }

        return handled;
    }

再看performIntercept,type为TYPE_ON_TOUCH,首先获取topmostChildList,这是把child按照z轴排序,最上面的排前面,CoordinatorLayout跟FrameLayout类似,越后边的child,在z轴上越靠上。所以,这里topmostChildList就是FloatingActionButton、AppBarLayout。然后在for循环里调用behavior的onTouchEvent。此时AppBarLayout.Behavior的onTouchEvent会返回true(具体后边分析),所以intercepted就为true,mBehaviorTouchView就会设置为AppBarLayout,然后performIntercept结束返回true。这个mBehaviorTouchView就相当于一般的ViewGroup里的mFirstTouchTarget的作用。再回头看上边代码,performIntercept返回true了,那就能进入L13,会调用mBehaviorTouchView.behavior.onTouchEvent,在这里把CoordinatorLayout的onTouchEvent,传递给了AppBarLayout.Behavior的onTouchEvent
而L16也会返回true,那整个CoordinatorLayout的onTouchEvent就返回true了,按照事件分发的规则,此时这个down事件被CoordinatorLayout消费了。但是实际上down事件的处理者是AppBarLayout.Behavior。他们之间通过mBehaviorTouchView连接。

    private boolean performIntercept(MotionEvent ev, final int type) {
        boolean intercepted = false;
        boolean newBlock = false;

        MotionEvent cancelEvent = null;

        final int action = MotionEventCompat.getActionMasked(ev);

        final List<View> topmostChildList = mTempList1;
        getTopSortedChildren(topmostChildList);

        // Let topmost child views inspect first
        final int childCount = topmostChildList.size();
        for (int i = 0; i < childCount; i++) {
            final View child = topmostChildList.get(i);
            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
            final Behavior b = lp.getBehavior();
            。。。

            if (!intercepted && b != null) {
                switch (type) {
                    case TYPE_ON_INTERCEPT:
                        intercepted = b.onInterceptTouchEvent(this, child, ev);
                        break;
                    case TYPE_ON_TOUCH:
                        intercepted = b.onTouchEvent(this, child, ev);
                        break;
                }
                if (intercepted) {
                    mBehaviorTouchView = child;
                }
            }

            ...
        }

        topmostChildList.clear();

        return intercepted;
    }

AppBarLayout.Behavior的onTouchEvent为何返回true

上文说了“此时AppBarLayout.Behavior的onTouchEvent会返回true”,我们来具体分析下。来看AppBarLayout.Behavior的onTouchEvent。AppBarLayout.Behavior的onTouchEvent代码在HeaderBehavior内,看L12只要触摸点在AppBarLayout内,而且canDragView,那就返回true,否则返回false。在AppBarLayout内明显是满足的,那就看canDragView。

   @Override
    public boolean onTouchEvent(CoordinatorLayout parent, V child, MotionEvent ev) {
        if (mTouchSlop < 0) {
            mTouchSlop = ViewConfiguration.get(parent.getContext()).getScaledTouchSlop();
        }

        switch (MotionEventCompat.getActionMasked(ev)) {
            case MotionEvent.ACTION_DOWN: {
                final int x = (int) ev.getX();
                final int y = (int) ev.getY();

                if (parent.isPointInChildBounds(child, x, y) && canDragView(child)) {
                    mLastMotionY = y;
                    mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
                    ensureVelocityTracker();
                } else {
                    return false;
                }
                break;
            }
            。。。        
        }

        if (mVelocityTracker != null) {
            mVelocityTracker.addMovement(ev);
        }

        return true;
    }

下边是AppBarLayout的canDragView,此时mLastNestedScrollingChildRef为null,所以走的是L16,返回true,那回头看上边的onTouchEvent也返回true。

    @Override
        boolean canDragView(AppBarLayout view) {
            if (mOnDragCallback != null) {
                // If there is a drag callback set, it's in control
                return mOnDragCallback.canDrag(view);
            }

            // Else we'll use the default behaviour of seeing if it can scroll down
            if (mLastNestedScrollingChildRef != null) {
                // If we have a reference to a scrolling view, check it
                final View scrollingView = mLastNestedScrollingChildRef.get();
                return scrollingView != null && scrollingView.isShown()
                        && !ViewCompat.canScrollVertically(scrollingView, -1);
            } else {
                // Otherwise we assume that the scrolling view hasn't been scrolled and can drag.
                return true;
            }
        }

ps

可以看出在CoordinatorLayout的onTouchEvent处理down事件的过程中,调用了2次AppBarLayout.Behavior的onTouchEvent

MOVE事件

由上文可知down事件被CoordinatorLayout消费,所以move事件不会走到CoordinatorLayout的onInterceptTouchEvent,而直接进入onTouchEvent。此时mBehaviorTouchView就是AppBarLayout。看L10,直接进入,然后把move事件发给了AppBarLayout.Behavior。

   @Override
    public boolean onTouchEvent(MotionEvent ev) {
        boolean handled = false;
        boolean cancelSuper = false;
        MotionEvent cancelEvent = null;

        final int action = MotionEventCompat.getActionMasked(ev);

        //此处会分发事件给behavior
        if (mBehaviorTouchView != null || (cancelSuper = performIntercept(ev, TYPE_ON_TOUCH))) {
            // Safe since performIntercept guarantees that
            // mBehaviorTouchView != null if it returns true
            final LayoutParams lp = (LayoutParams) mBehaviorTouchView.getLayoutParams();
            final Behavior b = lp.getBehavior();
            if (b != null) {
                handled = b.onTouchEvent(this, mBehaviorTouchView, ev);
            }
        }
            。。。

        return handled;
    }

AppBarLayout.Behavior处理move事件的代码比较简单,判断超过mTouchSlop就调用scroll,而scroll等于调用setHeaderTopBottomOffset。这里主要关注scroll的后2个参数,minOffset和maxOffset,minOffset传的是getMaxDragOffset(child)即AppBarlayout的-mDownScrollRange。这里就是AppBarlayout的可滑动范围,即toolbar的高度(包括margin)的负值。minOffset和maxOffset代表的是滑动上下限制,这个很好理解,因为移动的时候改的是top和bottom,比如top范围就是[initTop-滑动范围,initTop],所以这里的minOffset是-mDownScrollRange,maxOffset是0.

//HeaderBehavior
 @Override
    public boolean onTouchEvent(CoordinatorLayout parent, V child, MotionEvent ev) {
        if (mTouchSlop < 0) {
            mTouchSlop = ViewConfiguration.get(parent.getContext()).getScaledTouchSlop();
        }

        switch (MotionEventCompat.getActionMasked(ev)) {
            case MotionEvent.ACTION_MOVE: {
                final int activePointerIndex = MotionEventCompat.findPointerIndex(ev,
                        mActivePointerId);
                if (activePointerIndex == -1) {
                    return false;
                }

                final int y = (int) MotionEventCompat.getY(ev, activePointerIndex);
                int dy = mLastMotionY - y;

                if (!mIsBeingDragged && Math.abs(dy) > mTouchSlop) {
                    mIsBeingDragged = true;
                    if (dy > 0) {
                        dy -= mTouchSlop;
                    } else {
                        dy += mTouchSlop;
                    }
                }

                if (mIsBeingDragged) {
                    mLastMotionY = y;
                    // We're being dragged so scroll the ABL
                    scroll(parent, child, dy, getMaxDragOffset(child), 0);
                }
                break;
            }

        }

        if (mVelocityTracker != null) {
            mVelocityTracker.addMovement(ev);
        }

        return true;
    }

      final int scroll(CoordinatorLayout coordinatorLayout, V header,
            int dy, int minOffset, int maxOffset) {
        return setHeaderTopBottomOffset(coordinatorLayout, header,
                getTopBottomOffsetForScrollingSibling() - dy, minOffset, maxOffset);
    }

再看scroll里面,简单调用setHeaderTopBottomOffset,重点看第三个参数getTopBottomOffsetForScrollingSibling() - dy,这个算出来的就是经过这次move即将到达的offset(不是top哦,top=offset+mLayoutTop)。getTopBottomOffsetForScrollingSibling就是获取当前的偏移量,这个命名我不太理解。setHeaderTopBottomOffset就是给header设置一个新的offset,这个offset用一个min一个max来制约,很简单。setHeaderTopBottomOffset可以认为就是view的offsetTopAndBottom,调整top和bottom达到平移的效果

发现AppBarlayout对getTopBottomOffsetForScrollingSibling复写了,加了个mOffsetDelta,但是mOffsetDelta一直是0.

  @Override
        int getTopBottomOffsetForScrollingSibling() {
            return getTopAndBottomOffset() + mOffsetDelta;
        }

measure过程

http://blog.csdn.net/litefish/article/details/52327502曾经分析过简单情况下CoordinatorLayout的布局过程。这里稍有变化,主要在于第三次measure RelativeLayout的时候getScrollRange不再是0
final int height = availableHeight - header.getMeasuredHeight()
+ getScrollRange(header);
就是availableHeight-AppBar.measuredheight+toolbar高度,结果就是availableHeight。
所以此时RelativeLayout的最终measure高度是1731,这个高度是有意义的,他比不可滚动的appbar多了一个toolbar的高度,这么高的一个RelativeLayout在当前屏幕是放不下的,所以RelativeLayout往往会用一个可滚动的view来替换,比如Recyclerview或者NestedScrollView。

上滑可以滑到状态栏

上滑用的是setTopAndBottomOffset,并不会重新measure,layout,而fitSystemWindow是在measure,layout的时候发挥作用的

AppBarLayout的range

mTotalScrollRange 525
mDownPreScrollRange -1
mDownScrollRange 525

总结

1、ScrollView滑动的实现是通过修改scrollY,而AppBarLayout的实现是通过直接修改top和bottom的,其实就是把整个AppBarLayout内部的东西往上平移。
2、CoordinatorLayout里的mBehaviorTouchView就相当于一般的ViewGroup里的mFirstTouchTarget的作用
3、和嵌套滑动一样始终只有一个view可以fling,不可能A fling完 B fling

参考文章

http://dk-exp.com/2016/03/30/CoordinatorLayout/
http://www.jianshu.com/p/99adaad8d55c
https://code.google.com/p/android/issues/detail?id=177729

作者:litefish 发表于2016/9/19 18:36:27 原文链接
阅读:121 评论:0 查看评论

以OKHttp为基础封装网络请求工具类

$
0
0

特点:

1)支持SPDY协议,共享一个socket来处理同一个服务器的所有请求。

2)无缝支持GZIP,来减少数据流量。

3)缓存相应数据来减少重复的网络请求。

 

网络协议:

SPDY(读作“SPeeDY”)是Google开发的基于TCP的应用层协议,用以最小化网络延迟,提升网络速度,优化用户的网络使用体验SPDY并不是一种用于替代HTTP的协议,而是对HTTP协议的增强。新协议的功能包括数据流的多路复用、请求优先级以及HTTP报头压缩。(应用层Http、网络层、传输层协议) <Volley框架实使用了spdy协议>

 

常用类:

OKHttpClient(客户端对象)、

Request(访问请求)、 RequestBody(请求实体对象)

Response(响应类)、 ResponseBody(响应结果类)

FormEncodingBuilder(表单构造器)、

MediaType(数据类型)

 

response.isSuccessful() response.body().string()

client.newCall(request)


Activity中的代码:

package com.crs.demo.ui.okhttp;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import com.crs.demo.R;
import com.crs.demo.base.BaseActivity;
import com.crs.demo.constant.UrlConstant;
import com.google.gson.Gson;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.HashMap;

/**
 * Created on 2016/9/19.
 * Author:crs
 * Description:OKHttp网络请求框架的使用
 */
public class OKHttpActivity extends BaseActivity implements View.OnClickListener {

    private Button btn_ok_http_get;
    private Button btn_ok_http_post;
    private TextView tv_ok_http_content;

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

        initViews();
        initListener();

    }

    private void initViews() {
        btn_ok_http_get = findView(R.id.btn_ok_http_get);
        btn_ok_http_post = findView(R.id.btn_ok_http_post);
        tv_ok_http_content = findView(R.id.tv_ok_http_content);
    }

    private void initListener() {
        btn_ok_http_get.setOnClickListener(this);
        btn_ok_http_post.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_ok_http_get: {
                clickGet();
            }
            break;
            case R.id.btn_ok_http_post: {
                clickPost();
            }
            break;
        }
    }

    private void clickPost() {
        HttpUtils httpUtils = new HttpUtils();
        HashMap<String, String> params = new HashMap<>();
        params.put("orderNo", "TH01587458");
        httpUtils.post(UrlConstant.ORDER_STATUS_POST, params, new HttpUtils.BaseCallBack() {
            @Override
            public void onSuccess(Response response, String json) {
                JSONObject jsonObject;
                try {
                    jsonObject = new JSONObject(json);
                    String status = jsonObject.getString("Status");
                    tv_ok_http_content.setText(status);
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onFail(Request request, IOException e) {

            }

            @Override
            public void onError(Response response, int code) {

            }
        });
    }

    private void clickGet() {
        HttpUtils httpUtils = new HttpUtils();
        httpUtils.get(UrlConstant.ORDER_STATUS, new HttpUtils.BaseCallBack() {
            @Override
            public void onSuccess(Response response, String json) {
                //使用json包解析  注意注解的使用
                Gson gson = new Gson();
                {
                    Entity entity = gson.fromJson(json, Entity.class);
                    AfterSaleType afterSaleType = entity.getAfterSaleType();
                    String shopService = afterSaleType.getShopService();
                    tv_ok_http_content.setText(shopService);
                }

                //只能使用内部类的形式去封装对象,这样就不会报错
                {
                    //ResponseEntity responseEntity = gson.fromJson(json, ResponseEntity.class);
                    //ResponseEntity.AfterSaleType afterSaleType = responseEntity.getAfterSaleType();
                    //String shopService = afterSaleType.getShopServiceTousu();
                    //tv_ok_http_content.setText(shopService);
                }
            }

            @Override
            public void onFail(Request request, IOException e) {

            }

            @Override
            public void onError(Response response, int code) {

            }
        });
    }

}


网络请求工具类HttpUtils中的代码

注意事项:

1)接口回调(回调结果到Activity中)。

2)子线程与主线程通讯。

3)OKHttp的两个使用步骤。

package com.crs.demo.ui.okhttp;

import android.os.Handler;
import android.os.Looper;

import com.crs.demo.constant.IntConstant;
import com.crs.demo.utils.OKHttpUtils;
import com.google.gson.Gson;
import com.squareup.okhttp.Callback;
import com.squareup.okhttp.FormEncodingBuilder;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.RequestBody;
import com.squareup.okhttp.Response;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * Created on 2016/9/19.
 * Author:crs
 * Description:网络请求工具类的封装
 */
public class HttpUtils {

    private OkHttpClient client;
    private Handler mHandler;

    public HttpUtils() {
        client = new OkHttpClient();
        //设置连接超时时间,在网络正常的时候有效
        client.setConnectTimeout(IntConstant.REQUEST_TIME_OUT, TimeUnit.SECONDS);
        //设置读取数据的超时时间
        client.setReadTimeout(IntConstant.REQUEST_TIME_OUT, TimeUnit.SECONDS);
        //设置写入数据的超时时间
        client.setWriteTimeout(IntConstant.REQUEST_TIME_OUT, TimeUnit.SECONDS);

        //Looper.getMainLooper()  获取主线程的消息队列
        mHandler = new Handler(Looper.getMainLooper());
    }

    public void get(String url, BaseCallBack baseCallBack) {
        Request request = buildRequest(url, null, HttpMethodType.GET);
        sendRequest(request, baseCallBack);
    }


    public void post(String url, HashMap<String, String> params, BaseCallBack baseCallBack) {
        Request request = buildRequest(url, params, HttpMethodType.POST);
        sendRequest(request, baseCallBack);

    }

    /**
     * 1)获取Request对象
     *
     * @param url
     * @param params
     * @param httpMethodType 请求方式不同,Request对象中的内容不一样
     * @return Request 必须要返回Request对象, 因为发送请求的时候要用到此参数
     */
    private Request buildRequest(String url, HashMap<String, String> params, HttpMethodType httpMethodType) {
        //获取辅助类对象
        Request.Builder builder = new Request.Builder();
        builder.url(url);

        //如果是get请求
        if (httpMethodType == HttpMethodType.GET) {
            builder.get();
        } else {
            RequestBody body = buildFormData(params);
            builder.post(body);
        }

        //返回请求对象
        return builder.build();
    }

    /**
     * 2)发送网络请求
     *
     * @param request
     * @param baseCallBack
     */
    private void sendRequest(Request request, final BaseCallBack baseCallBack) {
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Request request, IOException e) {
                callBackFail(baseCallBack,request, e);
            }

            @Override
            public void onResponse(Response response) throws IOException {
                if (response.isSuccessful()) {
                    String json = response.body().string();
                    //此时请求结果在子线程里面,如何把结果回调到主线程里?
                    callBackSuccess(baseCallBack,response, json);
                } else {
                    callBackError(baseCallBack,response, response.code());
                }
            }
        });
    }


    /**
     * 主要用于构建请求参数
     *
     * @param param
     * @return ResponseBody
     */
    private RequestBody buildFormData(HashMap<String, String> param) {

        FormEncodingBuilder builder = new FormEncodingBuilder();
        //遍历HashMap集合
        if (param != null && !param.isEmpty()) {
            Set<Map.Entry<String, String>> entries = param.entrySet();
            for (Map.Entry<String, String> entity : entries) {
                String key = entity.getKey();
                String value = entity.getValue();
                builder.add(key, value);
            }
        }
        return builder.build();
    }

    //请求类型定义
    private enum HttpMethodType {
        GET,
        POST
    }

    //定义回调接口
    public interface BaseCallBack {
        void onSuccess(Response response, String json);

        void onFail(Request request, IOException e);

        void onError(Response response, int code);
    }



    //主要用于子线程和主线程进行通讯
   private void callBackSuccess(final BaseCallBack baseCallBack, final Response response, final String json){
       mHandler.post(new Runnable() {
           @Override
           public void run() {
               baseCallBack.onSuccess(response,json);
           }
       });
   }


    private void callBackError(final BaseCallBack baseCallBack, final Response response, final int code){
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                baseCallBack.onError(response,code);
            }
        });
    }

    private void callBackFail(final BaseCallBack baseCallBack, final Request request, final IOException e){
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                //相当于此run方法是在主线程执行的,可以进行更新UI的操作
                baseCallBack.onFail(request,e);
            }
        });
    }

}

实体模型的封装

注意事项: 

1)使用注解@SerializedName("Code") 修改字段名

2)不要使用内部类嵌套的形式封装实体模型

Entity模型

package com.crs.demo.ui.okhttp;

import com.google.gson.annotations.SerializedName;

/**
 * Created on 2016/9/19.
 * Author:crs
 * Description:请求结果实体模型
 */
public class Entity {
    @SerializedName("Code")
    private String code;
    @SerializedName("AfterSaleType")
    private AfterSaleType afterSaleType;

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public AfterSaleType getAfterSaleType() {
        return afterSaleType;
    }

    public void setAfterSaleType(AfterSaleType afterSaleType) {
        this.afterSaleType = afterSaleType;
    }
}

AfterSaleType模型:

package com.crs.demo.ui.okhttp;

import com.google.gson.annotations.SerializedName;

/**
 * Created on 2016/9/19.
 * Author:crs
 * Description:AfterSaleType实体模型
 */
public class AfterSaleType {
    @SerializedName("UnReceive")
    private String unReceive;
    @SerializedName("returnGoods")
    private String ReturnGoods;
    @SerializedName("ShopServiceTousu")
    private String ShopService;
    @SerializedName("ProductQuality")
    private String productQuality;
    @SerializedName("Invoice")
    private String invoice;
    @SerializedName("Other")
    private String other;

    public String getUnReceive() {
        return unReceive;
    }

    public void setUnReceive(String unReceive) {
        this.unReceive = unReceive;
    }

    public String getReturnGoods() {
        return ReturnGoods;
    }

    public void setReturnGoods(String returnGoods) {
        ReturnGoods = returnGoods;
    }

    public String getShopService() {
        return ShopService;
    }

    public void setShopService(String shopService) {
        ShopService = shopService;
    }

    public String getProductQuality() {
        return productQuality;
    }

    public void setProductQuality(String productQuality) {
        this.productQuality = productQuality;
    }

    public String getInvoice() {
        return invoice;
    }

    public void setInvoice(String invoice) {
        this.invoice = invoice;
    }

    public String getOther() {
        return other;
    }

    public void setOther(String other) {
        this.other = other;
    }
}

作者:chenrushui 发表于2016/9/19 18:41:53 原文链接
阅读:153 评论:0 查看评论

Android jni/ndk编程一:jni初级认识与实战体验

$
0
0

Android平台很多地方都可以看到jni的身影,比如之前接触到一个投屏的项目,主要的代码是c/c++写的,然后通过Jni供java层调用;另外,就拿Android系统中的Service来说,很多的Service都有java层代码和native层代码组成,native层代码会在android启动的过程中完成向java层的注册。总之,由于无法甩开jni的身影,所以我打算花点时间系统的学习下Android下的jni开发。

一.开发工具

所谓工欲善其事,必先利其器,在学习android系统的jni编程之前,先了解下jni编程使用的工具。1.1NDK(Native Development Kit)
NDK翻译过来就是本地代码开发工具集,本地代码主要指c/c++,因此,我们的c/c++代码可以使用NDK中提供的工具完成编译,我们可以把C/C++代码编译成动态库,然后在java层访问动态库,这样就是了java调用C/C++的功能。NDK众多的工具中,ndk-build主要用来编译native代码,它在windows和linux平台下均有响应的版本可以使用。它的用法似乎和在android源码下编译一个模块使用mm命令很相似。之所以说他们相似是因为他们都需要一个Android.mk文件,而且文件的格式完全一样,比如说有如下Android.mk:

      LOCAL_PATH := $(call my-dir)
      include $(CLEAR_VARS)

      LOCAL_MODULE_TAGS := optional
      LOCAL_PRELINK_MODULE := false


      LOCAL_SRC_FILES := hello.c
      LOCAL_MODULE := hello
      include $(BUILD_EXECUTABLE)

我们在Android源码目录下使用mm命令编译该模块和在windows下使用ndk-build编译该模块都能产生libhello.so库,表面上还真看不出差别。
使用ndk-build编译native代码时,除了需要Android.mk文件之外,可能有必要添加一个Application.mk,这个文件通常是由一行:

APP_ABI := x86

这里我们指明了需要编译的二进制库的格式。ABI(Application Binary Interface)与处理器相关,对于arm处理器,APP_ABI 可能要配置成 armeabi ,对于mips处理器,APP_ABI应该配置为mips,当然,我们还可以一次生成所有平台的库,此时只需要给APP_ABI赋值ALL就可以了。

二.jni的初步认识

2.1 JNI的作用

JNI(Java Native Interface)它提供了若干的API实现了Java和其他语言的通信(主要是C&C++)。从Java1.1开始,JNI标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。以上是百度百科上copy的话,也算是交代了下JNI的作用吧。

2.2 JNI使用流程

我们使用JNI的起点一般都是System.loadLibrary(“xxx”);开始的,xxx代表了需要加载的库名。可以认为是它加载我们c/c++代码到虚拟机中,这样,我们的Java虚拟机就知道了c/c++中的函数了,之后,我们就可以调用它。
因此,使用jni只需两步:
1.首先,我们要有一个动态库,这个库我们可以使用ndk-build来编译生成。
2.其次,我们需要使用System.loadLibrary(“xxx”)来加载这个库,加载完成后,就可以和本地代码交互了。
2.3 查阅一个使用JNI的c文件
为了认识JNI,找一个使用JNI的文件,比如:android-ndk\android-ndk-r10\samples\hello-gl2\jni\gl_code.cpp:

...
extern "C" {
    JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_init(JNIEnv * env, jobject obj,  jint width, jint height);
    JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_step(JNIEnv * env, jobject obj);
};

JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_init(JNIEnv * env, jobject obj,  jint width, jint height)
{
    setupGraphics(width, height);
}

JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_step(JNIEnv * env, jobject obj)
{
    r

这里节选了其中的一些,我们会发现其中有很多奇怪的字段,比如JNIEXPORT 、JNICALL等,所以,接下来,我们得先搞清楚它们的意义。

2.4 JNIEXPORT 和 JNICALL

这两个字段定义在jni.h中,定义如下:

#define JNIIMPORT
#define JNIEXPORT  __attribute__ ((visibility ("default")))
#define JNICALL __NDK_FPABI__

因为在在Windows中编译dll动态库时,如果动态库中的函数要被外部调用,需要在函数声明中添加 attribute ((visibility (“default”)))标识,表示将该函数导出在外部可以调用。在Linux/Unix系统中,这两个宏可以省略不加。因为在Linux/Unix平台下,这两个宏为空,所以加不加都没关系,当然还是建议加上哈,这样linux下的代码就可以直接拿到linux下编译了。

2.4 extern “C”

extern “C”从字面上看有两部分的内容:extern和“C”
extern是编程语言中的一种属性,它表征了变量、函数等类型的作用域(可见性)属性,是编程语言中的关键字。当进行编译时,该关键字告诉编译器它所声明的函数和变量等可以在本模块或者文件以及其他模块或文件中使用。
“C”表明了一种编译规约。
因此,extern “C”表明了一种编译规约,其中extern是关键字属性,“C”表征了编译器链接规范。
使用extern “C” 声明的函数将采用C语言的编译方式编译,也就是说只有在C++代码中extern “C”才有意义,之所以这样显示声明适应C语言的编译方式编译该代码块,是因为c和c++是有差异的,举例来说,有如下函数:
void hello(int,int);
这个函数在C编译器中,它的函数名师_hello,而在c++编译器中它的函数名是hello_int_int,之所以这样是因为c++支持函数重载,函数名可以相同,表征一个函数的除了函数名还有函数的参数列表。这因为有如此不同,因此我们可以想象如下情景:
加入我要在c++中调用一个c函数
1.首先,我要在hello.h中声明hello(int,int)函数,然后在对应的.c文件中实现它。
2.c++文件需要包含hello.h文件,然后执行hello(1,1);完成调用。
那么此时c编译器生成的函数名为_hello。而c++编译器会寻找_hello_int_int的函数名,这不就找不到了吗?
因此,extern “C”主要用于c++代码调用c代码时,避免出现函数找不到的问题。

三.JVM查找native代码的简要过程

JVM查找native方法有两种方式:
1.静态方式:按照JNI规范的命名规则
2.动态方式:调用JNI提供的RegisterNatives函数,将本地函数注册到JVM中。

3.1静态方式

静态方式使用的是按照JNI的命名规范来查找native函数,JNI函数命名规则为:
Java_类全路径_方法名
比如我们打算向com.jinwei.hellotest包中的MainActivity类注册名为sayHello的方法,那么,我们的函数命名就应该为:Java_com_jinwei_jnitesthello_MainActivity_sayHello

3.2动态方式

了解动态注册就要涉及到System.loadLibrary函数的工作流程了,这个函数打开一个动态库后,会找到JNI_OnLoad这个函数的地址,然后调用这个函数,因此我们可以在这个函数中完成向JVM注册native方法的工作。
比如,Android源码中有如下代码片段:

jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
{
    JNIEnv* env = NULL;
    jint result = -1;

    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
        ALOGE("ERROR: GetEnv failed\n");
        goto bail;
    }
    assert(env != NULL);

    if (register_android_media_ImageWriter(env) != JNI_OK) {
        ALOGE("ERROR: ImageWriter native registration failed");
        goto bail;
    }
    ...

JNI_OnLoad调用register_android_media_ImageWriter函数进一步注册native方法:

int register_android_media_ImageWriter(JNIEnv *env) {
...
    int ret2 = AndroidRuntime::registerNativeMethods(env,
                   "android/media/ImageWriter$WriterSurfaceImage", gImageMethods, NELEM(gImageMethods));

    return (ret1 || ret2);
}

该函数中使用AndroidRuntime::registerNativeMethods真正完成native方法的注册,这其中用到一个结构体:gImageMethods,其定义如下:

static JNINativeMethod gImageMethods[] = {
    {"nativeCreatePlanes",      "(II)[Landroid/media/ImageWriter$WriterSurfaceImage$SurfacePlane;",
                                                              (void*)Image_createSurfacePlanes },
    {"nativeGetWidth",         "()I",                         (void*)Image_getWidth },
    {"nativeGetHeight",        "()I",                         (void*)Image_getHeight },
    {"nativeGetFormat",        "()I",                         (void*)Image_getFormat },
};

它是一个函数映射表,前边是java层使用的函数名,后边是native层使用的函数名,中间是函数签名。
签名是一种用参数个数和类型区分同名方法的手段,即解决方法重载问题。
假如有下面Java方法:
long f (int n, String s, int[] arr);
签名后: “(ILjava/lang/String;[I)J”
其中要特别注意的是:
1. 类描述符开头的’L’与结尾的’;’必须要有
2. 数组描述符,开头的’[‘必须有.
3. 方法描述符规则: “(各参数描述符)返回值描述符”,其中参数描述符间没有任何分隔
符号
签名中使用的符号总结如下:
这里写图片描述

四.实战

4.1静态方式

在随便一个目录下添加如下三个文件:
hello.c,Android.mk,Application.mk
hello.c

#include <stdio.h>
#include <jni.h>
#include <stdlib.h>
JNIEXPORT jstring JNICALL Java_com_jinwei_jnitesthello_MainActivity_sayHello(JNIEnv * env, jobject obj){
    return (*env)->NewStringUTF(env,"jni say hello to you");
}

Android.mk

      LOCAL_PATH := $(call my-dir)
      include $(CLEAR_VARS)

      LOCAL_MODULE_TAGS := optional
      LOCAL_PRELINK_MODULE := false
      LOCAL_MODULE_PATH := hellolib


      LOCAL_SRC_FILES := hello.c
      LOCAL_MODULE := hello
      include $(BUILD_SHARED_LIBRARY)

Application.mk

APP_ABI := armeabi

然后使用cmd进入到该目录下,执行ndk-build。能执行ndk-build是因为我已经把ndk-build工具所在的目录添加到环境变量path中了。编译成功后会在上级目录的libs目录的armeabi目录下生成libhello.so文件。
在Android Studio工程的src/main下新建jniLibs目录,在jniLibs目录下新建armeabi目录,然后把libhello.so拷贝到armeabi目录下。这样,就可以在Android应用程序中访问libhello.so库了。关于jniLibs目录的名字,这是Android gradle默认的jni库目录,我们是可以自定义的,这里就不啰嗦了,可以参考下我的详细配置Android Studio中的Gradle
之后运行app就可以看到jni say hello to you的字样了。
一下是Android Studio中相关的文件:
MainActivity.java

package com.jinwei.jnitesthello;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
    TextView textView = null;
    static {
        System.loadLibrary("hello");
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.text);
        String hehe =  this.sayHello();
        textView.setText(hehe);
    }
    native public String sayHello();
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.jinwei.jnitesthello.MainActivity">

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!" />
</RelativeLayout>

4.2 动态方式

动态注册的使用流程之前已经分析过,它和静态的区别也只体现在hello.c文件上,这里只把hello.c文件贴出来:

#include <stdio.h>
#include <jni.h>
#include <stdlib.h>



jstring native_sayHello(JNIEnv * env, jobject obj){
    return (*env)->NewStringUTF(env,"jni say hello to you");
}

static JNINativeMethod gMethods[] = {  
{"sayHello", "()Ljava/lang/String;", (void *)native_sayHello},  
};  

JNIEXPORT jint  JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)  
{  
    JNIEnv* env = NULL; //注册时在JNIEnv中实现的,所以必须首先获取它
    jint result = -1;

    if((*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_4) != JNI_OK) //从JavaVM获取JNIEnv,一般使用1.4的版本
      return -1;

    jclass clazz;
    static const char* const kClassName="com/jinwei/jnitesthello/MainActivity";

    clazz = (*env)->FindClass(env, kClassName); //这里可以找到要注册的类,前提是这个类已经加载到java虚拟机中。 这里说明,动态库和有native方法的类之间,没有任何对应关系。

    if(clazz == NULL)
    {
      printf("cannot get class:%s\n", kClassName);
      return -1;
    }

    if((*env)->RegisterNatives(env,clazz,gMethods, sizeof(gMethods)/sizeof(gMethods[0]))!= JNI_OK) //这里就是关键了,把本地函数和一个java类方法关联起来。不管之前是否关联过,一律把之前的替换掉!
    {
      printf("register native method failed!\n");
      return -1;
    } 

    return JNI_VERSION_1_4;  
}

还是一样,使用ndk-build编译,把编译生成的库文件拷贝到android studio工程src/main/jniLibs/armeabi目录下,然后运行该项目即可。
注意:如果你的android设备或者虚拟机使用的x86等其他格式的镜像,注意修改Application.mk文件,修改方法文章的第一小节已经介绍过了。

总结:通过以上基础知识的介绍和两个实战的案例,我们应该初步理解了Jni工作的过程,对静态方式和动态方式使用JNI有了直观的体验,但JNI毕竟非常复杂,我们还有很多的知识要学习,下一节主要介绍jni类型的转换,就是怎么把java层的String,int等转换到c/c++层对应的类型。

作者:u011913612 发表于2016/9/19 18:53:47 原文链接
阅读:161 评论:0 查看评论

《React-Native系列》31、 Fetch发送POST请求的坑与解决方案

$
0
0
我们在请求http接口时候,通常都会使用get和post的方式,针对表单提交这类的请求,我们通常采用post方式。

那么在RN中的Fetch API中post提交有哪些坑呢?让我们撸起来。


我们先来说说Server端的代码,通常我们从Request获取参数时的方法为:
String paraValue = request.getParameter(paraName);
我们下面说的判断能不能获取参数,就是按照这种方法来获取。

在 RN中,通常我们会怎么写代码呢?
方案一(不推荐)
    let url = "http://127.0.0.1:8080/api/testFetch”
    let params = "name=admin&password=admin123”;
    fetch(url , {
      method: 'POST',
      headers: {},
      body: params,
    }).then((response) => {
      if (response.ok) {
          return response.json();
      }
    }).then((json) => {
      alert(JSON.stringify(json));
    }).catch((error) => {
      console.error(error);
    });

此时我们发现在Server端无法获取到name和password的值。
换成GET试试,将params追加到url后,发现ok。那这是什么情况呢?下面讲解。

好,不行,我们就再换一种方法试试呗。
方案二(不推荐):
    let params = {"name":"admin","password":"admin123"};
    
    fetch(url , {
      method: 'POST',
      headers: {},
      body:JSON.stringify(params),
    }).then((response) => {
      if (response.ok) {
          return response.json();
      }
    }).then((json) => {
      alert(JSON.stringify(json));
    }).catch((error) => {
      console.error(error);
    });
我们直接将params封装成一个JSON对象,然后在body里将JSON对象转成字符串传过去,发现然并卵,Server端还是获取不到值。


好,我们不兜圈子了,直接说明原因。
其实,方案一和方案二都是直接在body里传递了一个字符串,在Server端获取body的方式如下:
StringBuilder buffer = new StringBuilder();
BufferedReader reader = beat.getRequest().getReader();
String line;
 while ((line = reader.readLine()) != null) {
	buffer.append(line);
 }
String body = buffer.toString();
通过这种方法我们可以获取到传入的字符串。
既然能获取到字符串,那么我们也可以拿到我们传入的值了,可以转JSON、或者按&切割字符串,只不过这种解决方案好像有点挫啊!!!

也许你会问在jquery中,我们就是按照方案一这种方式做的啊,怎么好使呢?
答:因为参数 "name=admin&password=admin123” 在jquery中,传入对象框架会自动封装成formData的形式,fetch没有这个功能。

终极方案(推荐使用):

既然fetch不会自动转FormData,那我们自己new一个FormData,直接传给body。
在FormData中也可以传递字节流实现上传图片的功能。参考:http://blog.csdn.net/codetomylaw/article/details/52446786
     let formData = new FormData();
     formData.append("name","admin");
     formData.append("password","admin123");
    
    fetch(url , {
      method: 'POST',
      headers: {},
      body: formData,
    }).then((response) => {
      if (response.ok) {
          return response.json();
      }
    }).then((json) => {
      alert(JSON.stringify(json));
    }).catch((error) => {
      console.error(error);
    });
这样我们就可以在Server端获取到name和password的值了。
作者:hsbirenjie 发表于2016/9/19 19:24:39 原文链接
阅读:152 评论:0 查看评论

我的文档

$
0
0

iOS - 开发

1. Xcode在真机调试的时候出现”The identity used to sign the executable is no longer valid”

解决方案:
(1)provisioning Profile文件选择错误
(2)provisioning Profile已失效
(3)开发者证书过期或者被删除了

2. 将storyBoard里的控制器进行实例化

注:需要在Storyboard里面设置控制器的Storyboard ID

//Identifier:@“Storyboard ID”
//将storyBoard实例化 (1)(可以在AppDelegate里面使用)
    UIStoryboard *mainSB = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    //将要跳转控制器通过storyBoard实例化
    ViewController *VC = [mainSB instantiateViewControllerWithIdentifier:@"ViewController"];
    VC.isModifyPassword = NO;
    [self.navigationController pushViewController:VC animated:YES];

//将storyBoard实例化 (2)
//将要跳转控制器通过storyBoard实例化
    ViewController *VC = [self.storyboard  instantiateViewControllerWithIdentifier:@"ViewController"];
    VC.isModifyPassword = NO;
    [self.navigationController pushViewController:VC animated:YES];

3. 仿安卓Toast

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

//声明定义一个ToastLabel对象
@interface ToastLabel : UILabel

- (void)setMessageText:(NSString *)text;

@end

@interface Toast : NSObject
{

    ToastLabel *toastLabel;
    NSTimer *countTimer;
    NSInteger changeCount;
}

//创建声明单例的方法
+ (instancetype)shareInstance;

- (void)makeToast:(NSString *)message duration:(CGFloat )duation;

@end

#import "Toast.h"


@implementation ToastLabel

/**

 * ToastLabel初始化,位label设置各种属性
 *
 * @return ToastLabel

 */

- (instancetype)init{

    self = [super init];
    if (self) {
        self.layer.cornerRadius = 10;
        self.layer.masksToBounds = YES;
        self.backgroundColor = [UIColor blackColor];
        self.numberOfLines = 0;
        self.textAlignment = NSTextAlignmentCenter;
        self.textColor = [UIColor whiteColor];
        self.font = [UIFont systemFontOfSize:15];
    }
    return self;
}

/**
 * 设置显示的文字
 *
 * @aram text 文字文本
 */

- (void)setMessageText:(NSString *)text{
    [self setText:text];

    CGRect rect = [self.text boundingRectWithSize:CGSizeMake(DeviceWidth - 20, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:self.font} context:nil];

    CGFloat width = rect.size.width + 20;
    CGFloat height = rect.size.height + 20;
    CGFloat x = (DeviceWidth - width) / 2;
    CGFloat y = DeviceHight - height - 80;

    self.frame = CGRectMake(x, y, width, height);

}

@end

@implementation Toast

/**
 *  实现声明单例的方法 GCD
 *
 *  @return 单例
 */

+ (instancetype)shareInstance{

    static Toast *singleton = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{

        singleton = [[Toast alloc] init];

    });

    return singleton;
}

/**
 *  初始化方法
 *
 *  @return 自身
 *
 */

- (instancetype)init{

    self = [super init];
    if (self) {
        toastLabel = [[ToastLabel alloc] init];

        countTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(changeTime) userInfo:nil repeats:YES];
        countTimer.fireDate = [NSDate distantFuture];//关闭定时器
    }

    return self;
}

/**
 *  弹出并显示Tosat
 *
 *  @param message  显示的文本内容
 *  @param duration 显示时间
 */
- (void)makeToast:(NSString *)message duration:(CGFloat)duation{

    if ([message length] == 0) {
        return;
    }
    [toastLabel setMessageText:message];
    [[[UIApplication sharedApplication]keyWindow ] addSubview:toastLabel];

    toastLabel.alpha = 0.8;
    countTimer.fireDate = [NSDate distantPast];//开启定时器
    changeCount = duation;
}

/**
 *   定时器回调方法
 */

- (void)changeTime{

    //NSLog(@"时间:%ld",changeCount);
    if (changeCount-- <= 0) {
        countTimer.fireDate = [NSDate distantFuture];//关闭定时器
        [UIView animateWithDuration:0.2f animations:^{
            toastLabel.alpha = 0;
        } completion:^(BOOL finished) {
            [toastLabel removeFromSuperview];
        }];
    }
}

@end

//duration:显示的时长
[[Toast shareInstance] makeToast:@"你提示的内容" duration:1.0];

4. UITextField的左视图设置

//1.创建UITextField类别

#import <UIKit/UIKit.h>

@interface loginUITextField : UITextField

@end

//2.重写UITextField的左视图的Bounds
#import "loginUITextField.h"

@implementation loginUITextField

- (CGRect)leftViewRectForBounds:(CGRect)bounds

{
    CGRect rect = [super leftViewRectForBounds:bounds];

    if (self.window.frame.size.width == 320) {

        rect = CGRectMake(rect.origin.x + 3, rect.origin.y , 28, 28);

    } else if (self.window.frame.size.width == 375){

        rect = CGRectMake(rect.origin.x + 4, rect.origin.y , 32, 32);

    } else {

        rect = CGRectMake(rect.origin.x + 5, rect.origin.y , 35, 35);
    }

    return rect;
}

@end

//以下是例子  并不能直接使用
//_userTextField的左视图
    UIImageView *useImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"user"]];
    _userImageView.contentMode = UIViewContentModeScaleAspectFit;
    _userTextField.leftView = useImageView;
    _userTextField.leftViewMode = UITextFieldViewModeAlways;
    _userTextField.borderStyle = UITextBorderStyleRoundedRect;

    //修改水印字体颜色和字体大小
    [_userTextField setValue:[UIColor lightGrayColor] forKeyPath:@"_placeholderLabel.textColor"];
    [_userTextField setValue:[UIFont boldSystemFontOfSize:15] forKeyPath:@"_placeholderLabel.font"];


    //_passwordTxetField的左视图
    UIImageView *passwdImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"locked"]];
    //passwdImageView.frame = CGRectMake(0, 0, 37, 37);
    _passwordTxetField.contentMode = UIViewContentModeScaleAspectFit;
    _passwordTxetField.leftView = passwdImageView;
    _passwordTxetField.leftViewMode = UITextFieldViewModeAlways;
    _passwordTxetField.borderStyle = UITextBorderStyleRoundedRect;

    //修改水印字体颜色和字体大小
    [_passwordTxetField setValue:[UIColor lightGrayColor] forKeyPath:@"_placeholderLabel.textColor"];
    [_passwordTxetField setValue:[UIFont boldSystemFontOfSize:15] forKeyPath:@"_placeholderLabel.font"];

5. 自定义NavgationBar的标题和返回按钮无文字的样式和设置NavgationBar的背景图

//自定义NavgationBar的标题
- (void)creatdTitle{
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 45)];
    label.text = @"标题";
    label.font = [UIFont boldSystemFontOfSize:20];
    label.textAlignment = NSTextAlignmentCenter;
    label.textColor = [UIColor whiteColor];
    self.navigationItem.titleView = label;
}

//返回按钮无文字的样式
- (void)createdbackBarButtonItem{
    UIBarButtonItem *newBarButtonItem = [[UIBarButtonItem alloc] init];
    newBarButtonItem.title = @"";
    self.navigationItem.backBarButtonItem = newBarButtonItem;
    [self.navigationController.navigationBar setTintColor:[UIColor whiteColor]];
}

//设置NavgationBar的背景图 (jpg记得加后缀)
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"1"] forBarMetrics:UIBarMetricsDefault];

6. 自定义UIAlertController的标题、内容、和按钮的字体样式

- (void)created{

    NSString *str = @"注  销";

    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil message:str preferredStyle:UIAlertControllerStyleAlert];

    NSMutableAttributedString *alertControllerStr = [[NSMutableAttributedString alloc] initWithString:str];

    [alertControllerStr addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(0, str.length)];
    [alertControllerStr addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:25] range:NSMakeRange(0, str.length)];

        [alertController setValue:alertControllerStr forKey:@"attributedMessage"];

    UIAlertAction *confirmAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {



    }];

    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {

    }];
    [cancelAction setValue:[UIColor grayColor] forKey:@"titleTextColor"]; 

    [alertController addAction:confirmAction];
    [alertController addAction:cancelAction];

    [self presentViewController:alertController animated:YES completion:nil];

}

7. 验证码倒计时60S(注意UIButton样式不能用系统的会闪)

//self.verificationBtn:改成你自己的命名的button

- (void)startTime{
    __block int timeout = 59; //倒计时时间
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_source_t _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,queue);
    dispatch_source_set_timer(_timer,dispatch_walltime(NULL, 0),1.0*NSEC_PER_SEC, 0); //每秒执行

    dispatch_source_set_event_handler(_timer, ^{
        if(timeout<=0){ //倒计时结束,关闭
            dispatch_source_cancel(_timer);
            dispatch_async(dispatch_get_main_queue(), ^{
                //设置界面的按钮显示 根据自己需求设置(倒计时结束后调用)
                [self.verificationBtn setTitle:@"获取验证码" forState:UIControlStateNormal];
                [self.verificationBtn setBackgroundColor:[UIColor colorWithRed: 0/256.0 green: 111/256.0 blue: 255/256.0 alpha:1]];

                //设置可点击
                self.verificationBtn.userInteractionEnabled = YES;

            });
        }else{
            // int minutes = timeout / 60;    //这里注释掉了,这个是用来测试多于60秒时计算分钟的。
            int seconds = timeout % 60;
            NSString *strTime = [NSString stringWithFormat:@"%.2d", seconds];
            dispatch_async(dispatch_get_main_queue(), ^{
                //设置界面的按钮显示 根据自己需求设置
                //NSLog(@"____%@",strTime);
                [UIView beginAnimations:nil context:nil];
                [UIView setAnimationDuration:1];

                [self.verificationBtn setTitle:[NSString stringWithFormat:@"%@秒重新发送",strTime] forState:UIControlStateNormal];
                [UIView commitAnimations];
                self.verificationBtn.backgroundColor = [UIColor lightGrayColor];
                //设置不可点击
                self.verificationBtn.userInteractionEnabled = NO;

            });

            timeout--;
        }
    });

    dispatch_resume(_timer);

}

8. 各种切圆角(基本上能切得都这样切)

    //头像图片切圆
    _userImageView.layer.cornerRadius = _userImageView.frame.size.width / 2;
    _userImageView.layer.masksToBounds = YES;

    //
    _textFiled.layer.cornerRadius = 10;
    _textFiled.layer.masksToBounds = YES;

    //
    view.layer.cornerRadius = 20;
    view.layer.masksToBounds = YES;

9.避免程序因为NSNull而导致奔溃

//创建个类别
#import <Foundation/Foundation.h>

@interface NSNull (IsNull)

@end

#import "NSNull+IsNull.h"

@implementation NSNull (IsNull)

- (void)forwardInvocation:(NSInvocation *)invocation

{

    if ([self respondsToSelector:[invocation selector]]) {

        [invocation invokeWithTarget:self];

    }

}


- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector

{

    NSMethodSignature *sig = [[NSNull class] instanceMethodSignatureForSelector:selector];

    if(sig == nil) {

        sig = [NSMethodSignature signatureWithObjCTypes:"@^v^c"];

    }

    return sig;

}

@end

10.AFNetworking的一个小问题(获取数据的类型不对时,进行更改)

    manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/plain",@"text/html",@"image/jpg",nil];

11.极光推送程序内的代码

//1.创建一个类

#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>


@interface CFPushHelper : NSObject



///----------------------------------------------------
/// @name Setup 启动相关
///----------------------------------------------------
+ (NSString *)registrationID;
/*!
 * @abstract 启动SDK
 *
 * @param launchingOption 启动参数.
 * @param appKey 一个JPush 应用必须的,唯一的标识. 请参考 JPush 相关说明文档来获取这个标识.
 * @param channel 发布渠道. 可选.
 * @param isProduction 是否生产环境. 如果为开发状态,设置为 NO; 如果为生产状态,应改为 YES.
 * @param advertisingIdentifier 广告标识符(IDFA) 如果不需要使用IDFA,传nil.
 *
 * @discussion 提供SDK启动必须的参数, 来启动 SDK.
 * 此接口必须在 App 启动时调用, 否则 JPush SDK 将无法正常工作.
 */
+ (void)setupWithOption:(NSDictionary *)launchingOption
                 appKey:(NSString *)appKey
                channel:(NSString *)channel
       apsForProduction:(BOOL)isProduction
  advertisingIdentifier:(NSString *)advertisingId;

///----------------------------------------------------
/// @name APNs about 通知相关
///----------------------------------------------------

/*!
 * @abstract 注册要处理的远程通知类型
 *
 * @param types 通知类型
 * @param categories
 *
 * @discussion
 */
//+ (void)registerForRemoteNotificationTypes:(NSUInteger)types
//                                categories:(NSSet *)categories;

//上传deviceToken
+ (void)registerDeviceToken:(NSData *)deviceToken;


/*!
 * @abstract 处理收到的 APNs 消息
 */
//+ (void)handleRemoteNotification:(NSDictionary *)userInfo;


// ios7以后,才有completion,否则传nil
+ (void)handleRemoteNotification:(NSDictionary *)userInfo completion:(void (^)(UIBackgroundFetchResult))completion;

/*!
 * @abstract 前台展示本地推送
 *
 * @param notification 本地推送对象
 * @param notificationKey 需要前台显示的本地推送通知的标示符
 *
 * @discussion 默认App在前台运行时不会进行弹窗,在程序接收通知调用此接口可实现指定的推送弹窗。
 */
+ (void)showLocalNotificationAtFront:(UILocalNotification *)notification identifierKey:(NSString *)notificationKey;

@end

//导入极光推送头文件@"JPUSHService.h"

#import "CFPushHelper.h"
#import "JPUSHService.h"

@implementation CFPushHelper

+ (NSString *)registrationID{

   return [JPUSHService registrationID];

}

+ (void)setupWithOption:(NSDictionary *)launchingOption appKey:(NSString *)appKey channel:(NSString *)channel apsForProduction:(BOOL)isProduction advertisingIdentifier:(NSString *)advertisingId{

    //Required
    if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) {
        //可以添加自定义categories
        [JPUSHService registerForRemoteNotificationTypes:(UIUserNotificationTypeBadge |
                                                          UIUserNotificationTypeSound |
                                                          UIUserNotificationTypeAlert)
                                              categories:nil];
    } else {
        //categories 必须为nil
        [JPUSHService registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge |
                                                          UIRemoteNotificationTypeSound |
                                                          UIRemoteNotificationTypeAlert)
                                              categories:nil];
    }
    //Required
    // 如需继续使用pushConfig.plist文件声明appKey等配置内容,请依旧使用[JPUSHService setupWithOption:launchOptions]方式初始化。
    [JPUSHService setupWithOption:launchingOption appKey:appKey
                          channel:channel
                 apsForProduction:isProduction
            advertisingIdentifier:advertisingId];

    return;

}

+ (void)registerDeviceToken:(NSData *)deviceToken{

    [JPUSHService registerDeviceToken:deviceToken];

    return;
}

//+ (void)handleRemoteNotification:(NSDictionary *)userInfo{
//    
//    [CFPushHelper handleRemoteNotification:userInfo];
//    
//}

+ (void)handleRemoteNotification:(NSDictionary *)userInfo completion:(void (^)(UIBackgroundFetchResult))completion{

    [JPUSHService handleRemoteNotification:userInfo];

    if (completion) {

        completion(UIBackgroundFetchResultNewData);
    }
    return;

}

+ (void)showLocalNotificationAtFront:(UILocalNotification *)notification
                       identifierKey:(NSString *)notificationKey{

    [CFPushHelper showLocalNotificationAtFront:notification identifierKey:nil];

    return;
}


@end

//我这里创建的AppDelegate的类别

#import "AppDelegate.h"

@interface AppDelegate (CFPushSDK)

- (void)JPushapplication:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;

@end


#import "AppDelegate+CFPushSDK.h"
#import "JPUSHService.h"
#import "CFPushHelper.h"

#define JPushSDK_AppKey @"顾名思义"
#define isProduction    NO

@implementation AppDelegate (CFPushSDK)

- (void)JPushapplication:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{

    [CFPushHelper setupWithOption:launchOptions appKey:JPushSDK_AppKey channel:nil apsForProduction:isProduction advertisingIdentifier:nil];

    //注册
    NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
    [defaultCenter addObserver:self selector:@selector(networkDidReceiveMessage:) name:kJPFNetworkDidLoginNotification object:nil];

}

//通知方法
- (void)networkDidReceiveMessage:(NSNotification *)notification {

    //调用接口
    NSLog(@"\n\n极光推送注册成功\n\n");

    //通知后台registrationID
    //NSLog(@"registrationID2 = %@",[CFPushHelper registrationID]);
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    if (![CFPushHelper registrationID]) {

        NSString *registrationID = @"123";
        [defaults setObject:registrationID forKey:@"registrationID"];

    } else {

        [defaults setObject:[CFPushHelper registrationID] forKey:@"registrationID"];

    }
    [defaults synchronize];
    //[CFPushHelper registrationID]
    //注销通知
    [[NSNotificationCenter defaultCenter] removeObserver:self name:kJPFNetworkDidLoginNotification object:nil];

}

- (void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {

    /// Required - 注册 DeviceToken
    //NSLog(@"%@", [NSString stringWithFormat:@"Device Token: %@", deviceToken]);
    [CFPushHelper registerDeviceToken:deviceToken];

}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {

    // IOS 7 Support Required
    [CFPushHelper handleRemoteNotification:userInfo completion:completionHandler];

    // 应用正处理前台状态下,不会收到推送消息,因此在此处需要额外处理一下
    if (application.applicationState == UIApplicationStateActive) {
        UIAlertView *alert = [[UIAlertView alloc]
                              initWithTitle:@"收到推送消息"
                              message:userInfo[@"aps"][@"alert"]
                              delegate:nil
                              cancelButtonTitle:@"取消"
                              otherButtonTitles:@"确定",nil];
        [alert show];
    }  

    //[self gotoViewControllerWith:userInfo];
    [self gotoViewController];


}

- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{

    //NSLog(@"did Fail To Register For Remote Notifications With Error : %@",error);

    return;
}

- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification{

    [CFPushHelper showLocalNotificationAtFront:notification identifierKey:nil];

    return;
}

- (void)applicationDidBecomeActive:(UIApplication *)application{

    [application setApplicationIconBadgeNumber:0];
    [application cancelAllLocalNotifications];

    return;
}

@end

#import "AppDelegate.h"
#import "JPUSHService.h"

@interface AppDelegate ()

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.

    //注册极光推送
    [self JPushapplication:application didFinishLaunchingWithOptions:launchOptions];

  return YES;

}

暂时就这样

作者:asdbbilaa 发表于2016/9/19 20:14:46 原文链接
阅读:118 评论:0 查看评论
Viewing all 5930 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>