Android 实践:做一款新闻 APP

跟代码相关的工作,大多唯手熟尔,所以这里花了点时间做了款简易版的新闻 APP,虽然都是些基础的内容,不过还是可以加深自己对部分代码的理解。至少,可以加深自己的记忆


步骤


  1. 依赖库
  2. 网络请求
  3. 网络解析
  4. 界面布局
  5. 最后
  6. 运行界面
  7. 运行GIF
  8. 完整代码下载地址(github)

依赖库


过程中需要用到一些开源依赖库文件,先在 build.grade 中声明:

    compile 'com.google.code.gson:gson:2.8.0'       //网络解析
    compile 'com.squareup.okhttp3:okhttp:3.7.0'     //网络请求
    compile 'com.github.bumptech.glide:glide:3.8.0' //图片加载
    compile 'com.android.support:design:24.2.1'     //Material Design中用到的依赖库
    compile 'de.hdodenhof:circleimageview:2.1.0'    //显示圆形图片

网络请求


在包下创建一个文件夹 util 用来存放工具类,创建文件 HttpUtil.class 用来请求数据:

public class HttpUtil {
    public static void sendOkHttpRequest(String address, okhttp3.Callback callback){
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(address).build();
        client.newCall(request).enqueue(callback);
    }
}

这里用到的是 okhttp3.Callback 的回调接口,结果会返回到 callback 的回调函数中,后面会进行处理


网络解析


我们先从数据解析开始,毕竟这才是这个小项目的重点。这次项目使用的数据来源是天行数据(http://www.tianapi.com/ )的新闻资讯 API ,先看 API 的说明:

Android 实践:做一款新闻 APP_第1张图片

可以看到返回数据为 JSON, 默认返回 10 条参数。请求地址为:

这里写图片描述

其中, APIKEY 需要用个人的 API KEY 代替,可以在个人中心中看到,其他的请求地址也是大同小异

这里写图片描述

JSON 返回示例:

Android 实践:做一款新闻 APP_第2张图片

还有错误返回码,用来判断返回数据的异常情况:

Android 实践:做一款新闻 APP_第3张图片

根据 gson 的返回示例,我们可以写出对应的实体类文件,通过 gson 将返回数据转化为对应的类型。先创建一个 gson 文件夹存放实体类文件。

在 gson 文件夹下创建 New.class 文件:

public class News {
    @SerializedName("ctime")
    public String time;

    public String title;

    public String description;

    public String picUrl;

    public String url;

}

创建 NewsList.class 文件:

public class NewsList {

    public int code;

    public String msg;

    @SerializedName("newslist")
    public List newsList ;

}

至此,我们就已经创建好了与返回数据对应的实体类。

在 util 文件夹下创建文件 Utility.class 文件:

public class Utility {
    public static NewsList parseJsonWithGson(final String requestText){
        Gson gson = new Gson();
        return gson.fromJson(requestText, NewsList.class);
    }

}

将请求得到的数据解析为 NewList 实体类对象。现在网络请求和解析都准备好了,就开始界面文件了


界面布局


修改 values 目录下的 styles.xml 文件:

<resources>
    
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        -- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary
        "colorPrimaryDark">@color/colorPrimary
        "colorAccent">@color/colorAccent
    style>

resources>

修改通知栏颜色和标题栏颜色一样,是处于视觉统一的原因,也可以不修改(非必须)


主要采用的是 Material Design 的设计,整体布局采用的是滑动菜单,主界面内容为 ToolBar 和 ListView(这里为了方便,就直接使用),侧边栏内容为 NavigationView


主界面:
因为要用 ToolBar 替代 ActionBar, 我们先修改 values 下面的 styles 文件,修改主题为:

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">

在layout 下创建 nav_header 文件


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="180dp"
    android:background="@color/colorPrimary"
    android:padding="10dp">

    <de.hdodenhof.circleimageview.CircleImageView
        android:id="@+id/icon_image"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:layout_centerInParent="true"
        android:src="@drawable/nav_icon" />

    <TextView
        android:id="@+id/username"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:text="https://github.com/lentitude"
        android:textColor="@color/color_White"
        android:textSize="14sp" />


    <TextView
        android:id="@+id/mail"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@id/username"
        android:text="lentitude"
        android:textColor="@color/color_White"
        android:textSize="14sp" />

RelativeLayout>

这里在头部文件中放置了一个CircleImageView,两个 TextView,没有什么理解难度


在 res 目录下创建 menu 文件夹,新建 nav_menu.xml 文件:

version="1.0" encoding="utf-8"?>
"http://schemas.android.com/apk/res/android">
    "single">
        <item
            android:id="@+id/nav_society"
            android:title="社会新闻" />
        <item
            android:id="@+id/nav_county"
            android:title="国内新闻" />
        <item
            android:id="@+id/nav_internation"
            android:title="国际新闻" />
        <item
            android:id="@+id/nav_fun"
            android:title="娱乐新闻" />
        <item
            android:id="@+id/nav_sport"
            android:title="体育新闻" />
        <item
            android:id="@+id/nav_nba"
            android:title="NBA新闻" />
        <item
            android:id="@+id/nav_football"
            android:title="足球新闻" />
        <item
            android:id="@+id/nav_technology"
            android:title="科技新闻" />
        <item
            android:id="@+id/nav_work"
            android:title="创业新闻" />
        <item
            android:id="@+id/nav_apple"
            android:title="苹果新闻" />
        <item
            android:id="@+id/nav_war"
            android:title="军事新闻" />
        <item
            android:id="@+id/nav_internet"
            android:title="移动互联" />
        <item
            android:id="@+id/nav_travel"
            android:title="旅游咨询" />
        <item
            android:id="@+id/nav_health"
            android:title="健康知识" />
        <item
            android:id="@+id/nav_strange"
            android:title="奇闻异事" />
        <item
            android:id="@+id/nav_looker"
            android:title="美女图片" />
        <item
            android:id="@+id/nav_vr"
            android:title="VR科技" />
        <item
            android:id="@+id/nav_it"
            android:title="IT资讯" />


    

这里创建了若干个 ITEM 子项,只有 title,没有 icon,大家可以自行放置

主界面 activity_main.xml:

"1.0" encoding="utf-8"?>
.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    .support.design.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        .support.design.widget.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            .support.v7.widget.Toolbar
                android:id="@+id/tool_bar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:contentInsetStart="0dp"
                app:titleTextColor="@color/color_White"
                android:background="@color/colorPrimary"
                />


        .support.design.widget.AppBarLayout>


        .support.v4.widget.SwipeRefreshLayout
            android:id="@+id/swipe_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior">

            "@+id/list_view"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:divider="@color/color_Background"
                android:dividerHeight="1dp"

                />


        .support.v4.widget.SwipeRefreshLayout>

    .support.design.widget.CoordinatorLayout>


    .support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:headerLayout="@layout/nav_header"
        app:menu="@menu/nav_menu"
        />


.support.v4.widget.DrawerLayout>

因为是一步到位,所以……大家最好之前用过使用过相同的布局设计(比如:第一行代码)

DrawerLayout 中有两个直接子布局文件:
1. CoordinatorLayout:一种 FrameLayout, 作为显示主界面内容的最外层布局
2. NavigationView:作为显示侧边栏的最外层布局,不过已经封装好了,可以直接通过 app:headerLayout 和 app:menu 属性引用之前我们已经写好的 头部和菜单布局文件

CoordinatorLayout 中有两个直接子布局文件:
1. AppBarLayout :通过 AppBarLayout 属性,可以将 ToolBar 和 ListView 分隔开,可以对滚动事件进行响应,实现 Material 效果
2. SwipeRefreshLayout:用来刷新 ListView 中的内容

创建 list_view_item.xml 文件,设计 ListView 的子项布局:


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="100dp"
    android:background="@color/color_White">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="10dp">

        <ImageView
            android:id="@+id/title_pic"
            android:layout_width="80dp"
            android:layout_height="60dp"
            android:layout_centerVertical="true"
            android:layout_alignParentRight="true"
            android:scaleType="centerCrop"/>

        <TextView
            android:id="@+id/title_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="16sp"
            android:layout_marginRight="10dp"
            android:layout_alignTop="@+id/title_pic"
            android:layout_alignParentLeft="true"
            android:layout_toLeftOf="@+id/title_pic"
            />

        <TextView
            android:id="@+id/descr_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="8sp"
            android:layout_marginRight="10dp"
            android:layout_alignBottom="@+id/title_pic"
            android:layout_alignParentLeft="true"
            />

    RelativeLayout>


RelativeLayout>

子项布局内包含 3 个控件,ImageView 显示返回的图片,TextView 显示返回的标题和出处

创建一个 Title.class类:

public class Title {
    private String title;
    private String descr;
    private String imageUrl;
    private String uri;

    public Title(String title,String descr, String imageUrl, String uri){
        this.title = title;
        this.imageUrl = imageUrl;
        this.descr = descr;
        this.uri = uri;
    }

    public String getTitle() {
        return title;
    }

    public String getImageUrl() {
        return imageUrl;
    }

    public String getDescr() {
        return descr;
    }

    public String getUri() {
        return uri;
    }
}

这里之所以除了 标题,出处,图片显示在 ListViw 中,uri 传入另一个布局,显示内容文件

接下来就是 TitleAdapter.class

public class TitleAdapter extends ArrayAdapter<Title> {
    private int resourceId;

    public TitleAdapter(@NonNull Context context, @LayoutRes int resource, @NonNull List objects) {
        <span class="hljs-keyword">super</span>(context, resource, objects);
        resourceId = resource;
    }

    <span class="hljs-annotation">@NonNull</span>
    <span class="hljs-annotation">@Override</span>
    public View getView(int position, <span class="hljs-annotation">@Nullable</span> View convertView, <span class="hljs-annotation">@NonNull</span> ViewGroup parent) {
        Title title = getItem(position);
        View view;
        ViewHolder viewHolder;
        <span class="hljs-javadoc">/**
         * 缓存布局和实例,优化 listView
         */</span>
        <span class="hljs-keyword">if</span> (convertView == <span class="hljs-keyword">null</span>){
            view = LayoutInflater.from(getContext()).inflate(resourceId,parent,<span class="hljs-keyword">false</span>);
            viewHolder = <span class="hljs-keyword">new</span> ViewHolder();
            viewHolder.titleText = (TextView)view.findViewById(R.id.title_text);
            viewHolder.titlePic = (ImageView) view.findViewById(R.id.title_pic);
            viewHolder.titleDescr = (TextView)view.findViewById(R.id.descr_text);
            view.setTag(viewHolder);
        }<span class="hljs-keyword">else</span>{
            view = convertView;
            viewHolder = (ViewHolder) view.getTag();
        }

        Glide.<span class="hljs-keyword">with</span>(getContext()).load(title.getImageUrl()).into(viewHolder.titlePic);
        viewHolder.titleText.setText(title.getTitle());
        viewHolder.titleDescr.setText(title.getDescr());

        <span class="hljs-keyword">return</span> view;

    }

    public <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ViewHolder</span>{</span>
        TextView titleText;
        TextView titleDescr;
        ImageView titlePic;
    }
}
</code></pre> 
  <p>这里还是一样的老套路,通过convertView 来缓存布局,通过类 ViewHolder 缓存控件实例,这样做,可以节省 50% 的效率,所以还是按照老套路走吧。</p> 
  <p>接下来就是 Activity 文件 MainActivity.class:</p> 
  <pre class="prettyprint"><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MainActivity</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">AppCompatActivity</span> {</span>
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span>  ITEM_SOCIETY= <span class="hljs-number">1</span>;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span>  ITEM_COUNTY= <span class="hljs-number">2</span>;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span>  ITEM_INTERNATION= <span class="hljs-number">3</span>;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span>  ITEM_FUN= <span class="hljs-number">4</span>;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span>  ITEM_SPORT= <span class="hljs-number">5</span>;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span>  ITEM_NBA= <span class="hljs-number">6</span>;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span>  ITEM_FOOTBALL= <span class="hljs-number">7</span>;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span>  ITEM_TECHNOLOGY= <span class="hljs-number">8</span>;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span>  ITEM_WORK= <span class="hljs-number">9</span>;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span>  ITEM_APPLE= <span class="hljs-number">10</span>;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span>  ITEM_WAR= <span class="hljs-number">11</span>;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span>  ITEM_INTERNET= <span class="hljs-number">12</span>;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span>  ITEM_TREVAL= <span class="hljs-number">13</span>;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span>  ITEM_HEALTH= <span class="hljs-number">14</span>;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span>  ITEM_STRANGE= <span class="hljs-number">15</span>;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span>  ITEM_LOOKER= <span class="hljs-number">16</span>;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span>  ITEM_VR= <span class="hljs-number">17</span>;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span>  ITEM_IT= <span class="hljs-number">18</span>;


    <span class="hljs-keyword">private</span> List<Title> titleList = <span class="hljs-keyword">new</span> ArrayList<Title>();
    <span class="hljs-keyword">private</span> ListView listView;
    <span class="hljs-keyword">private</span> TitleAdapter adapter;
    <span class="hljs-keyword">private</span> NavigationView navigationView;
    <span class="hljs-keyword">private</span> DrawerLayout drawerLayout;
    <span class="hljs-keyword">private</span> SwipeRefreshLayout refreshLayout;


    <span class="hljs-annotation">@Override</span>
    <span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onCreate</span>(Bundle savedInstanceState) {
        <span class="hljs-keyword">super</span>.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Toolbar toolbar = (Toolbar)findViewById(R.id.tool_bar);
        setSupportActionBar(toolbar);
        <span class="hljs-keyword">final</span> ActionBar actionBar = getSupportActionBar();
        <span class="hljs-keyword">if</span> (actionBar != <span class="hljs-keyword">null</span>){
            actionBar.setDisplayHomeAsUpEnabled(<span class="hljs-keyword">true</span>);
            actionBar.setHomeAsUpIndicator(R.drawable.ic_menu);
        }
        actionBar.setDisplayShowTitleEnabled(<span class="hljs-keyword">true</span>);
        actionBar.setTitle(<span class="hljs-string">"社会新闻"</span>);

        refreshLayout = (SwipeRefreshLayout)findViewById(R.id.swipe_layout);
        refreshLayout.setColorSchemeColors(getResources().getColor(R.color.colorPrimary));
        listView = (ListView)findViewById(R.id.list_view);
        adapter = <span class="hljs-keyword">new</span> TitleAdapter(<span class="hljs-keyword">this</span>,R.layout.list_view_item, titleList);
        listView.setAdapter(adapter);
        listView.setOnItemClickListener(<span class="hljs-keyword">new</span> AdapterView.OnItemClickListener() {
            Intent intent = <span class="hljs-keyword">new</span> Intent(MainActivity.<span class="hljs-keyword">this</span>, ContentActivity.class);
            <span class="hljs-annotation">@Override</span>
            <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onItemClick</span>(AdapterView<?> parent, View view, <span class="hljs-keyword">int</span> position, <span class="hljs-keyword">long</span> id) {
                Title title = titleList.get(position);
                intent.putExtra(<span class="hljs-string">"title"</span>,actionBar.getTitle());
                intent.putExtra(<span class="hljs-string">"uri"</span>,title.getUri());
                startActivity(intent);
            }
        });

        drawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout);
        navigationView = (NavigationView)findViewById(R.id.nav_view);
        navigationView.setCheckedItem(R.id.nav_society);
        navigationView.setNavigationItemSelectedListener(<span class="hljs-keyword">new</span> NavigationView.OnNavigationItemSelectedListener() {
            <span class="hljs-annotation">@Override</span>
            <span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">onNavigationItemSelected</span>(@NonNull MenuItem item) {
                <span class="hljs-keyword">switch</span> (item.getItemId()){
                    <span class="hljs-keyword">case</span> R.id.nav_society:
                        handleCurrentPage(<span class="hljs-string">"社会新闻"</span>,ITEM_SOCIETY);
                        <span class="hljs-keyword">break</span>;
                    <span class="hljs-keyword">case</span> R.id.nav_county:
                        handleCurrentPage(<span class="hljs-string">"国内新闻"</span>,ITEM_COUNTY);
                        <span class="hljs-keyword">break</span>;
                    <span class="hljs-keyword">case</span> R.id.nav_internation:
                        handleCurrentPage(<span class="hljs-string">"国际新闻"</span>,ITEM_INTERNATION);
                        <span class="hljs-keyword">break</span>;
                    <span class="hljs-keyword">case</span> R.id.nav_fun:
                        handleCurrentPage(<span class="hljs-string">"娱乐新闻"</span>,ITEM_FUN);
                        <span class="hljs-keyword">break</span>;
                    <span class="hljs-keyword">case</span> R.id.nav_sport:
                        handleCurrentPage(<span class="hljs-string">"体育新闻"</span>,ITEM_SPORT);
                        <span class="hljs-keyword">break</span>;
                    <span class="hljs-keyword">case</span> R.id.nav_nba:
                        handleCurrentPage(<span class="hljs-string">"NBA新闻"</span>,ITEM_NBA);
                        <span class="hljs-keyword">break</span>;
                    <span class="hljs-keyword">case</span> R.id.nav_football:
                        handleCurrentPage(<span class="hljs-string">"足球新闻"</span>,ITEM_FOOTBALL);
                        <span class="hljs-keyword">break</span>;
                    <span class="hljs-keyword">case</span> R.id.nav_technology:
                        handleCurrentPage(<span class="hljs-string">"科技新闻"</span>,ITEM_TECHNOLOGY);
                        <span class="hljs-keyword">break</span>;
                    <span class="hljs-keyword">case</span> R.id.nav_work:
                        handleCurrentPage(<span class="hljs-string">"创业新闻"</span>,ITEM_WORK);
                        <span class="hljs-keyword">break</span>;
                    <span class="hljs-keyword">case</span> R.id.nav_apple:
                        handleCurrentPage(<span class="hljs-string">"苹果新闻"</span>,ITEM_APPLE);
                        <span class="hljs-keyword">break</span>;
                    <span class="hljs-keyword">case</span> R.id.nav_war:
                        handleCurrentPage(<span class="hljs-string">"军事新闻"</span>,ITEM_WAR);
                        <span class="hljs-keyword">break</span>;
                    <span class="hljs-keyword">case</span> R.id.nav_internet:
                        handleCurrentPage(<span class="hljs-string">"移动互联"</span>,ITEM_INTERNET);
                        <span class="hljs-keyword">break</span>;
                    <span class="hljs-keyword">case</span> R.id.nav_travel:
                        handleCurrentPage(<span class="hljs-string">"旅游资讯"</span>,ITEM_TREVAL);
                        <span class="hljs-keyword">break</span>;
                    <span class="hljs-keyword">case</span> R.id.nav_health:
                        handleCurrentPage(<span class="hljs-string">"健康知识"</span>,ITEM_HEALTH);
                        <span class="hljs-keyword">break</span>;
                    <span class="hljs-keyword">case</span> R.id.nav_strange:
                        handleCurrentPage(<span class="hljs-string">"奇闻异事"</span>,ITEM_STRANGE);
                        <span class="hljs-keyword">break</span>;
                    <span class="hljs-keyword">case</span> R.id.nav_looker:
                        handleCurrentPage(<span class="hljs-string">"美女图片"</span>,ITEM_LOOKER);
                        <span class="hljs-keyword">break</span>;
                    <span class="hljs-keyword">case</span> R.id.nav_vr:
                        handleCurrentPage(<span class="hljs-string">"VR科技"</span>,ITEM_VR);
                        <span class="hljs-keyword">break</span>;
                    <span class="hljs-keyword">case</span> R.id.nav_it:
                        handleCurrentPage(<span class="hljs-string">"IT资讯"</span>,ITEM_IT);
                        <span class="hljs-keyword">break</span>;
                    <span class="hljs-keyword">default</span>:
                        <span class="hljs-keyword">break</span>;
                }
                drawerLayout.closeDrawers();
                <span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>;
            }
        });

        refreshLayout.setOnRefreshListener(<span class="hljs-keyword">new</span> SwipeRefreshLayout.OnRefreshListener() {
            <span class="hljs-annotation">@Override</span>
            <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onRefresh</span>() {
                refreshLayout.setRefreshing(<span class="hljs-keyword">true</span>);
                <span class="hljs-keyword">int</span> itemName = parseString((String)actionBar.getTitle());
                requestNew(itemName);
            }
        });

        requestNew(ITEM_SOCIETY);

    }

    <span class="hljs-javadoc">/**
     *  判断是否是当前页面,如果不是则 请求处理数据
     */</span>
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">handleCurrentPage</span>(String text, <span class="hljs-keyword">int</span> item){
        ActionBar actionBar = getSupportActionBar();
        <span class="hljs-keyword">if</span> (!text.equals(actionBar.getTitle().toString())){
            actionBar.setTitle(text);
            requestNew(item);
            refreshLayout.setRefreshing(<span class="hljs-keyword">true</span>);
        }
    }


    <span class="hljs-javadoc">/**
     * 请求处理数据
     */</span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">requestNew</span>(<span class="hljs-keyword">int</span> itemName){

        <span class="hljs-comment">// 根据返回到的 URL 链接进行申请和返回数据</span>
        String address = response(itemName);    <span class="hljs-comment">// key</span>
        HttpUtil.sendOkHttpRequest(address, <span class="hljs-keyword">new</span> Callback() {
            <span class="hljs-annotation">@Override</span>
            <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onFailure</span>(Call call, IOException e) {
                runOnUiThread(<span class="hljs-keyword">new</span> Runnable() {
                    <span class="hljs-annotation">@Override</span>
                    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">run</span>() {
                        Toast.makeText(MainActivity.<span class="hljs-keyword">this</span>, <span class="hljs-string">"新闻加载失败"</span>, Toast.LENGTH_SHORT).show();
                    }
                });
            }

            <span class="hljs-annotation">@Override</span>
            <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onResponse</span>(Call call, Response response) <span class="hljs-keyword">throws</span> IOException {
                <span class="hljs-keyword">final</span> String responseText = response.body().string();
                <span class="hljs-keyword">final</span> NewsList newlist = Utility.parseJsonWithGson(responseText);
                <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> code = newlist.code;
                <span class="hljs-keyword">final</span> String msg = newlist.msg;
                <span class="hljs-keyword">if</span> (code == <span class="hljs-number">200</span>){
                    titleList.clear();
                    <span class="hljs-keyword">for</span> (News news:newlist.newsList){
                        Title title = <span class="hljs-keyword">new</span> Title(news.title,news.description,news.picUrl, news.url);
                        titleList.add(title);
                    }

                    runOnUiThread(<span class="hljs-keyword">new</span> Runnable() {
                        <span class="hljs-annotation">@Override</span>
                        <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">run</span>() {
                            adapter.notifyDataSetChanged();
                            listView.setSelection(<span class="hljs-number">0</span>);
                            refreshLayout.setRefreshing(<span class="hljs-keyword">false</span>);
                        };
                    });
                }<span class="hljs-keyword">else</span>{
                    runOnUiThread(<span class="hljs-keyword">new</span> Runnable() {
                        <span class="hljs-annotation">@Override</span>
                        <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">run</span>() {
                            Toast.makeText(MainActivity.<span class="hljs-keyword">this</span>, <span class="hljs-string">"数据错误返回"</span>,Toast.LENGTH_SHORT).show();
                            refreshLayout.setRefreshing(<span class="hljs-keyword">false</span>);
                        }
                    });
                }



            }
        });


    }

    <span class="hljs-javadoc">/**
     * 输入不同的类型选项,返回对应的 URL 链接
     */</span>
    <span class="hljs-keyword">private</span> String <span class="hljs-title">response</span>(<span class="hljs-keyword">int</span> itemName){
        String address = <span class="hljs-string">"https://api.tianapi.com/social/?key=339a8b166f397f008236e596616a5f54&num=50&rand=1"</span>;
        <span class="hljs-keyword">switch</span>(itemName){
            <span class="hljs-keyword">case</span> ITEM_SOCIETY:
                <span class="hljs-keyword">break</span>;
            <span class="hljs-keyword">case</span> ITEM_COUNTY:
                address = address.replaceAll(<span class="hljs-string">"social"</span>,<span class="hljs-string">"guonei"</span>);
                <span class="hljs-keyword">break</span>;
            <span class="hljs-keyword">case</span> ITEM_INTERNATION:
                address = address.replaceAll(<span class="hljs-string">"social"</span>,<span class="hljs-string">"world"</span>);
                <span class="hljs-keyword">break</span>;
            <span class="hljs-keyword">case</span> ITEM_FUN:
                address = address.replaceAll(<span class="hljs-string">"social"</span>,<span class="hljs-string">"huabian"</span>);
                <span class="hljs-keyword">break</span>;
            <span class="hljs-keyword">case</span> ITEM_SPORT:
                address = address.replaceAll(<span class="hljs-string">"social"</span>,<span class="hljs-string">"tiyu"</span>);
                <span class="hljs-keyword">break</span>;
            <span class="hljs-keyword">case</span> ITEM_NBA:
                address = address.replaceAll(<span class="hljs-string">"social"</span>,<span class="hljs-string">"nba"</span>);
                <span class="hljs-keyword">break</span>;
            <span class="hljs-keyword">case</span> ITEM_FOOTBALL:
                address = address.replaceAll(<span class="hljs-string">"social"</span>,<span class="hljs-string">"football"</span>);
                <span class="hljs-keyword">break</span>;
            <span class="hljs-keyword">case</span> ITEM_TECHNOLOGY:
                address = address.replaceAll(<span class="hljs-string">"social"</span>,<span class="hljs-string">"keji"</span>);
                <span class="hljs-keyword">break</span>;
            <span class="hljs-keyword">case</span> ITEM_WORK:
                address = address.replaceAll(<span class="hljs-string">"social"</span>,<span class="hljs-string">"startup"</span>);
                <span class="hljs-keyword">break</span>;
            <span class="hljs-keyword">case</span> ITEM_APPLE:
                address = address.replaceAll(<span class="hljs-string">"social"</span>,<span class="hljs-string">"apple"</span>);
                <span class="hljs-keyword">break</span>;
            <span class="hljs-keyword">case</span> ITEM_WAR:
                address = address.replaceAll(<span class="hljs-string">"social"</span>,<span class="hljs-string">"military"</span>);
                <span class="hljs-keyword">break</span>;
            <span class="hljs-keyword">case</span> ITEM_INTERNET:
                address = address.replaceAll(<span class="hljs-string">"social"</span>,<span class="hljs-string">"mobile"</span>);
                <span class="hljs-keyword">break</span>;
            <span class="hljs-keyword">case</span> ITEM_TREVAL:
                address = address.replaceAll(<span class="hljs-string">"social"</span>,<span class="hljs-string">"travel"</span>);
                <span class="hljs-keyword">break</span>;
            <span class="hljs-keyword">case</span> ITEM_HEALTH:
                address = address.replaceAll(<span class="hljs-string">"social"</span>,<span class="hljs-string">"health"</span>);
                <span class="hljs-keyword">break</span>;
            <span class="hljs-keyword">case</span> ITEM_STRANGE:
                address = address.replaceAll(<span class="hljs-string">"social"</span>,<span class="hljs-string">"qiwen"</span>);
                <span class="hljs-keyword">break</span>;
            <span class="hljs-keyword">case</span> ITEM_LOOKER:
                address = address.replaceAll(<span class="hljs-string">"social"</span>,<span class="hljs-string">"meinv"</span>);
                <span class="hljs-keyword">break</span>;
            <span class="hljs-keyword">case</span> ITEM_VR:
                address = address.replaceAll(<span class="hljs-string">"social"</span>,<span class="hljs-string">"vr"</span>);
                <span class="hljs-keyword">break</span>;
            <span class="hljs-keyword">case</span> ITEM_IT:
                address = address.replaceAll(<span class="hljs-string">"social"</span>,<span class="hljs-string">"it"</span>);
                <span class="hljs-keyword">break</span>;
            <span class="hljs-keyword">default</span>:
        }
        <span class="hljs-keyword">return</span> address;
    }

    <span class="hljs-javadoc">/**
     * 通过 actionbar.getTitle() 的参数,返回对应的 ItemName
     */</span>
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> <span class="hljs-title">parseString</span>(String text){
        <span class="hljs-keyword">if</span> (text.equals(<span class="hljs-string">"社会新闻"</span>)){
            <span class="hljs-keyword">return</span> ITEM_SOCIETY;
        }
        <span class="hljs-keyword">if</span> (text.equals(<span class="hljs-string">"国内新闻"</span>)){
            <span class="hljs-keyword">return</span> ITEM_COUNTY;
        }
        <span class="hljs-keyword">if</span> (text.equals(<span class="hljs-string">"国际新闻"</span>)){
            <span class="hljs-keyword">return</span> ITEM_INTERNATION;
        }
        <span class="hljs-keyword">if</span> (text.equals(<span class="hljs-string">"娱乐新闻"</span>)){
            <span class="hljs-keyword">return</span> ITEM_FUN;
        }
        <span class="hljs-keyword">if</span> (text.equals(<span class="hljs-string">"体育新闻"</span>)){
            <span class="hljs-keyword">return</span> ITEM_SPORT;
        }
        <span class="hljs-keyword">if</span> (text.equals(<span class="hljs-string">"NBA新闻"</span>)){
            <span class="hljs-keyword">return</span> ITEM_NBA;
        }
        <span class="hljs-keyword">if</span> (text.equals(<span class="hljs-string">"足球新闻"</span>)){
            <span class="hljs-keyword">return</span> ITEM_FOOTBALL;
        }
        <span class="hljs-keyword">if</span> (text.equals(<span class="hljs-string">"科技新闻"</span>)){
            <span class="hljs-keyword">return</span> ITEM_TECHNOLOGY;
        }
        <span class="hljs-keyword">if</span> (text.equals(<span class="hljs-string">"创业新闻"</span>)){
            <span class="hljs-keyword">return</span> ITEM_WORK;
        }
        <span class="hljs-keyword">if</span> (text.equals(<span class="hljs-string">"苹果新闻"</span>)){
            <span class="hljs-keyword">return</span> ITEM_APPLE;
        }
        <span class="hljs-keyword">if</span> (text.equals(<span class="hljs-string">"军事新闻"</span>)){
            <span class="hljs-keyword">return</span> ITEM_WAR;
        }
        <span class="hljs-keyword">if</span> (text.equals(<span class="hljs-string">"移动互联"</span>)){
            <span class="hljs-keyword">return</span> ITEM_INTERNET;
        }
        <span class="hljs-keyword">if</span> (text.equals(<span class="hljs-string">"旅游资讯"</span>)){
            <span class="hljs-keyword">return</span> ITEM_TREVAL;
        }
        <span class="hljs-keyword">if</span> (text.equals(<span class="hljs-string">"健康知识"</span>)){
            <span class="hljs-keyword">return</span> ITEM_HEALTH;
        }
        <span class="hljs-keyword">if</span> (text.equals(<span class="hljs-string">"奇闻异事"</span>)){
            <span class="hljs-keyword">return</span> ITEM_STRANGE;
        }
        <span class="hljs-keyword">if</span> (text.equals(<span class="hljs-string">"美女图片"</span>)){
            <span class="hljs-keyword">return</span> ITEM_LOOKER;
        }
        <span class="hljs-keyword">if</span> (text.equals(<span class="hljs-string">"VR科技"</span>)){
            <span class="hljs-keyword">return</span> ITEM_VR;
        }
        <span class="hljs-keyword">if</span> (text.equals(<span class="hljs-string">"IT资讯"</span>)){
            <span class="hljs-keyword">return</span> ITEM_IT;
        }
        <span class="hljs-keyword">return</span> ITEM_SOCIETY;
    }

    <span class="hljs-javadoc">/**
     * 对侧边栏按钮进行处理,打开侧边栏
     */</span>
    <span class="hljs-annotation">@Override</span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">onOptionsItemSelected</span>(MenuItem item) {
        <span class="hljs-keyword">switch</span> (item.getItemId()){
            <span class="hljs-keyword">case</span> android.R.id.home:
                drawerLayout.openDrawer(GravityCompat.START);
                <span class="hljs-keyword">break</span>;
            <span class="hljs-keyword">default</span>:
        }
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>;
    }

    <span class="hljs-javadoc">/**
     * 对返回键进行处理,如果侧边栏打开则关闭侧边栏,否则关闭 activity
     */</span>
    <span class="hljs-annotation">@Override</span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onBackPressed</span>() {
        <span class="hljs-keyword">if</span>(drawerLayout.isDrawerOpen(GravityCompat.START)){
            drawerLayout.closeDrawers();
        }<span class="hljs-keyword">else</span>{
            finish();
        }
    }
}
</code></pre> 
  <p>本文的代码量虽然很大,只是比较繁琐,因为需要根据点击的 ITEM 来对不同的 接口地址提出申请,大部分的函数功能都有进行注释,所以略过了</p> 
  <pre class="prettyprint"><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">requestNew</span>(<span class="hljs-keyword">int</span> itemName){

        <span class="hljs-comment">// 根据返回到的 URL 链接进行申请和返回数据</span>
        String address = response(itemName);    <span class="hljs-comment">// key</span>
        HttpUtil.sendOkHttpRequest(address, <span class="hljs-keyword">new</span> Callback() {
            <span class="hljs-annotation">@Override</span>
            <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onFailure</span>(Call call, IOException e) {
                runOnUiThread(<span class="hljs-keyword">new</span> Runnable() {
                    <span class="hljs-annotation">@Override</span>
                    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">run</span>() {
                        Toast.makeText(MainActivity.<span class="hljs-keyword">this</span>, <span class="hljs-string">"新闻加载失败"</span>, Toast.LENGTH_SHORT).show();
                    }
                });
            }

            <span class="hljs-annotation">@Override</span>
            <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onResponse</span>(Call call, Response response) <span class="hljs-keyword">throws</span> IOException {
                <span class="hljs-keyword">final</span> String responseText = response.body().string();
                <span class="hljs-keyword">final</span> NewsList newlist = Utility.parseJsonWithGson(responseText);
                <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> code = newlist.code;
                <span class="hljs-keyword">final</span> String msg = newlist.msg;
                <span class="hljs-keyword">if</span> (code == <span class="hljs-number">200</span>){
                    titleList.clear();
                    <span class="hljs-keyword">for</span> (News news:newlist.newsList){
                        Title title = <span class="hljs-keyword">new</span> Title(news.title,news.description,news.picUrl, news.url);
                        titleList.add(title);
                    }

                    runOnUiThread(<span class="hljs-keyword">new</span> Runnable() {
                        <span class="hljs-annotation">@Override</span>
                        <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">run</span>() {
                            adapter.notifyDataSetChanged();
                            listView.setSelection(<span class="hljs-number">0</span>);
                            refreshLayout.setRefreshing(<span class="hljs-keyword">false</span>);
                        };
                    });
                }<span class="hljs-keyword">else</span>{
                    runOnUiThread(<span class="hljs-keyword">new</span> Runnable() {
                        <span class="hljs-annotation">@Override</span>
                        <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">run</span>() {
                            Toast.makeText(MainActivity.<span class="hljs-keyword">this</span>, <span class="hljs-string">"数据错误返回"</span>,Toast.LENGTH_SHORT).show();
                            refreshLayout.setRefreshing(<span class="hljs-keyword">false</span>);
                        }
                    });
                }



            }
        });


    }</code></pre> 
  <ol> 
   <li>外部调用时传入 itemName 参数,通过 response() 函数得到所需要请求数据的地址</li> 
   <li>通过sendOkHttpRequest() 回调方法,在返回数据成功的 onResponse() 方法中使用 parseJsonWithGson() 方法获取对应的实体类</li> 
   <li>将实体类中的数据添加到 Title对应中,将 Title 对象添加到 titleList 中,最后通过 runOnUiThread() 方法,切换到主线程提醒适配器进行数据更新。</li> 
  </ol> 
  <p>至此,主界面的代码逻辑都已经处理好了,还有 ListView 子项布局的点击事件处理:</p> 
  <pre class="prettyprint"><code class="hljs cs">listView.setOnItemClickListener(<span class="hljs-keyword">new</span> AdapterView.OnItemClickListener() {
            Intent intent = <span class="hljs-keyword">new</span> Intent(MainActivity.<span class="hljs-keyword">this</span>, ContentActivity.class);
            @Override
            <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onItemClick</span>(AdapterView<?> parent, View view, <span class="hljs-keyword">int</span> position, <span class="hljs-keyword">long</span> id) {
                Title title = titleList.<span class="hljs-keyword">get</span>(position);
                intent.putExtra(<span class="hljs-string">"title"</span>,actionBar.getTitle());
                intent.putExtra(<span class="hljs-string">"uri"</span>,title.getUri());
                startActivity(intent);
            }
        });</code></pre> 
  <p>在点击 ListView 子项布局时,会传入 标题栏文本 和 内容 URL</p> 
  <p>文件 activity_content.xml:</p> 
  <pre class="prettyprint"><code class="hljs avrasm"><?xml version=<span class="hljs-string">"1.0"</span> encoding=<span class="hljs-string">"utf-8"</span>?>
<android<span class="hljs-preprocessor">.support</span><span class="hljs-preprocessor">.design</span><span class="hljs-preprocessor">.widget</span><span class="hljs-preprocessor">.CoordinatorLayout</span>
    xmlns:android=<span class="hljs-string">"http://schemas.android.com/apk/res/android"</span>
    xmlns:app=<span class="hljs-string">"http://schemas.android.com/apk/res-auto"</span>
    android:layout_width=<span class="hljs-string">"match_parent"</span>
    android:layout_height=<span class="hljs-string">"match_parent"</span>
    android:background=<span class="hljs-string">"@color/color_White"</span>>

    <android<span class="hljs-preprocessor">.support</span><span class="hljs-preprocessor">.design</span><span class="hljs-preprocessor">.widget</span><span class="hljs-preprocessor">.AppBarLayout</span>
        android:layout_width=<span class="hljs-string">"match_parent"</span>
        android:layout_height=<span class="hljs-string">"wrap_content"</span>
        >

        <android<span class="hljs-preprocessor">.support</span><span class="hljs-preprocessor">.v</span>7<span class="hljs-preprocessor">.widget</span><span class="hljs-preprocessor">.Toolbar</span>
            android:id=<span class="hljs-string">"@+id/tool_bar"</span>
            android:layout_width=<span class="hljs-string">"match_parent"</span>
            android:layout_height=<span class="hljs-string">"?attr/actionBarSize"</span>
            app:titleTextColor=<span class="hljs-string">"@color/color_White"</span>
            app:theme=<span class="hljs-string">"@style/ThemeOverlay.AppCompat.Light"</span>
            app:layout_scrollFlags=<span class="hljs-string">"enterAlways|snap|scroll"</span>/>

    </android<span class="hljs-preprocessor">.support</span><span class="hljs-preprocessor">.design</span><span class="hljs-preprocessor">.widget</span><span class="hljs-preprocessor">.AppBarLayout</span>>


    <WebView
        android:id=<span class="hljs-string">"@+id/web_view"</span>
        android:layout_width=<span class="hljs-string">"match_parent"</span>
        android:layout_height=<span class="hljs-string">"match_parent"</span>
        app:layout_behavior=<span class="hljs-string">"@string/appbar_scrolling_view_behavior"</span>/>



</android<span class="hljs-preprocessor">.support</span><span class="hljs-preprocessor">.design</span><span class="hljs-preprocessor">.widget</span><span class="hljs-preprocessor">.CoordinatorLayout</span>>
</code></pre> 
  <p>如果了解了 activity_main.xml 的布局,这个布局也就没什么难度了,主要是新增了 WebView 控件,用来显示传入的 URL</p> 
  <p>文件 ContentActivity.class:</p> 
  <pre class="prettyprint"><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ContentActivity</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">AppCompatActivity</span> {</span>
    <span class="hljs-keyword">private</span> WebView webView;


    <span class="hljs-annotation">@Override</span>
    <span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onCreate</span>(Bundle savedInstanceState) {
        <span class="hljs-keyword">super</span>.onCreate(savedInstanceState);
        setContentView(R.layout.activity_content);

        Toolbar toolbar = (Toolbar)findViewById(R.id.tool_bar);
        setSupportActionBar(toolbar);
        ActionBar actionBar = getSupportActionBar();
        <span class="hljs-keyword">if</span> (actionBar != <span class="hljs-keyword">null</span>){
            actionBar.setDisplayHomeAsUpEnabled(<span class="hljs-keyword">true</span>);
            actionBar.setHomeAsUpIndicator(R.drawable.ic_back);
        }

        webView = (WebView)findViewById(R.id.web_view);
        webView.getSettings().setJavaScriptEnabled(<span class="hljs-keyword">true</span>);
        webView.setWebViewClient(<span class="hljs-keyword">new</span> WebViewClient());

        String uri = getIntent().getStringExtra(<span class="hljs-string">"uri"</span>);
        String title = getIntent().getStringExtra(<span class="hljs-string">"title"</span>);
        actionBar.setDisplayShowTitleEnabled(<span class="hljs-keyword">true</span>);
        actionBar.setTitle(title);
        webView.loadUrl(uri);

    }

    <span class="hljs-javadoc">/**
     * 点击返回键做了处理
     */</span>
    <span class="hljs-annotation">@Override</span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">onOptionsItemSelected</span>(MenuItem item) {
        <span class="hljs-keyword">switch</span> (item.getItemId()){
            <span class="hljs-keyword">case</span> android.R.id.home:
                finish();
                <span class="hljs-keyword">break</span>;
            <span class="hljs-keyword">default</span>:
        }
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>;
    }
}
</code></pre> 
  <p>显示传入的 URL网址</p> 
  <hr> 
  <p><strong>最后</strong></p> 
  <hr> 
  <p>到这里就结束了 ? 如果你认为都结束了,那你可以就需要面对打开应用之后马上闪退的情况了…….<strong>权限</strong> </p> 
  <p>我们还没有对权限进行申请,在 AndroidManifest 文件中添加声明:</p> 
  <pre class="prettyprint"><code class="hljs xml"><span class="hljs-tag"><<span class="hljs-title">uses-permission</span> <span class="hljs-attribute">android:name</span>=<span class="hljs-value">"android.permission.INTERNET"</span>/></span></code></pre> 
  <p>不过个人还是建议把 权限的考虑放在最先的优先级,毕竟养成这个习惯,就可以专注于代码的 bug…………………..</p> 
  <hr> 
  <p><strong>运行界面</strong></p> 
  <hr> 
  <p></p> 
  <center> 
   <a href="http://img.e-com-net.com/image/info8/09a2c7e4d26d48b0a7ffebe20c1fe389.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/09a2c7e4d26d48b0a7ffebe20c1fe389.jpg" alt="Android 实践:做一款新闻 APP_第4张图片" title="" width="301" height="532" style="border:1px solid black;"></a> 
   <br> (主界面) 
  </center> 
  <p></p> 
  <p></p> 
  <center> 
   <a href="http://img.e-com-net.com/image/info8/46113cfdcbb541978628956825d8b91b.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/46113cfdcbb541978628956825d8b91b.jpg" alt="Android 实践:做一款新闻 APP_第5张图片" title="" width="298" height="531" style="border:1px solid black;"></a> 
   <br> (侧边栏) 
  </center> 
  <p></p> 
  <p></p> 
  <center> 
   <a href="http://img.e-com-net.com/image/info8/d406e8b301f64462830cb0d5fb6cb189.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/d406e8b301f64462830cb0d5fb6cb189.jpg" alt="Android 实践:做一款新闻 APP_第6张图片" title="" width="302" height="535" style="border:1px solid black;"></a> 
   <br> (内容界面) 
  </center> 
  <p></p> 
  <hr> 
  <p><strong>运行 GIF</strong></p> 
  <hr> 
  <p></p> 
  <center>  
   <br> (由于大小限制,所以就只能传这么大了) 
  </center> 
  <p></p> 
  <hr> 
  <p><strong>完整代码下载地址</strong></p> 
  <hr> 
  <p>https://github.com/lentitude/NewsMD</p> 
 </div> 
</div>
                            </div>
                        </div>
                    </div>
                    <!--PC和WAP自适应版-->
                    <div id="SOHUCS" sid="1292185866545995776"></div>
                    <script type="text/javascript" src="/views/front/js/chanyan.js"></script>
                    <!-- 文章页-底部 动态广告位 -->
                    <div class="youdao-fixed-ad" id="detail_ad_bottom"></div>
                </div>
                <div class="col-md-3">
                    <div class="row" id="ad">
                        <!-- 文章页-右侧1 动态广告位 -->
                        <div id="right-1" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad">
                            <div class="youdao-fixed-ad" id="detail_ad_1"> </div>
                        </div>
                        <!-- 文章页-右侧2 动态广告位 -->
                        <div id="right-2" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad">
                            <div class="youdao-fixed-ad" id="detail_ad_2"></div>
                        </div>
                        <!-- 文章页-右侧3 动态广告位 -->
                        <div id="right-3" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad">
                            <div class="youdao-fixed-ad" id="detail_ad_3"></div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div class="container">
        <h4 class="pt20 mb15 mt0 border-top">你可能感兴趣的:(Android)</h4>
        <div id="paradigm-article-related">
            <div class="recommend-post mb30">
                <ul class="widget-links">
                    <li><a href="/article/1938851545382711296.htm"
                           title="Memfault 简介及在Nordic nRF91 系列 DK的应用" target="_blank">Memfault 简介及在Nordic nRF91 系列 DK的应用</a>
                        <span class="text-muted"></span>

                        <div>1:Memfault是一个云平台,它允许您和您的团队持续监控设备、调试固件问题,并将OTA更新部署到您的设备群,从而以软件的速度交付硬件产品。Memfault以嵌入式优先:支持运行在任何实时操作系统(RTOS)或Android、Linux等操作系统上的嵌入式系统和设备它适用于任何设备:从功能强大的SoC一直到功能受限的MCU,Memfault都能适配您设备的可用闪存、RAM和带宽我们的SDK是专为</div>
                    </li>
                    <li><a href="/article/1938849908421357568.htm"
                           title="安卓开发 手动构建 .so" target="_blank">安卓开发 手动构建 .so</a>
                        <span class="text-muted">XCZHONGS</span>
<a class="tag" taget="_blank" href="/search/android/1.htm">android</a>
                        <div>手动构建.so(兼容废弃ABI)下载旧版NDK(推荐r16b)地址:https://developer.android.com/ndk/downloads/older_releases下载NDKr16b(最后支持armeabi、mips、mips64的版本)使用ndk-build手动构建(不使用Gradle)在源文件目录下执行D:\ideal\androidstudio\sdk\ndk\16.1.</div>
                    </li>
                    <li><a href="/article/1938842215711305728.htm"
                           title="【开源项目】「安卓原生3D开源渲染引擎」:Sceneform‑EQR" target="_blank">【开源项目】「安卓原生3D开源渲染引擎」:Sceneform‑EQR</a>
                        <span class="text-muted"></span>

                        <div>「安卓原生3D开源渲染引擎」:Sceneform‑EQR渲染引擎“那一夜凌晨3点,第一次提交PR的手在抖……”——我深刻体会这种忐忑与激动。仓库地址:(github.com)。一、前言:开源对我意味着什么DIY的自由Vs.工业化的束缚刚入Android原生开发时,我习惯自己在项目里嵌入各种3D渲染/AR/XR模块,结构臃肿、流程混乱。当我知道GoogleSceneformSDK被弃用,起初只是出于</div>
                    </li>
                    <li><a href="/article/1938817641108008960.htm"
                           title="uniappx 安卓app项目本地打包运行,腾讯地图报错:‘鉴权失败,请检查你的key‘" target="_blank">uniappx 安卓app项目本地打包运行,腾讯地图报错:‘鉴权失败,请检查你的key‘</a>
                        <span class="text-muted">夏木。。。</span>
<a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/uniappx/1.htm">uniappx</a>
                        <div>根目录下添加AndroidManifest.xml文件,manifest.json文件中添加:"app":{"distribute":{"android":{"permissions":["",""],},"sdkConfigs":{"maps":{"qqmap":{"appkey_android":"腾讯地图key"}}}}},如此操作之后,重新自定义调试基座,运行模拟器,选择自定义基座:运行成</div>
                    </li>
                    <li><a href="/article/1938817639287681024.htm"
                           title="Uniapp跟原生android插件交互发信息(二)" target="_blank">Uniapp跟原生android插件交互发信息(二)</a>
                        <span class="text-muted">飞露</span>
<a class="tag" taget="_blank" href="/search/uni-app/1.htm">uni-app</a><a class="tag" taget="_blank" href="/search/android/1.htm">android</a><a class="tag" taget="_blank" href="/search/%E4%BA%A4%E4%BA%92/1.htm">交互</a>
                        <div>一、背景在uni-app开发过程中,有时候会遇到uni-app插件或者提供的api对硬件操作不太友好,需要使用原生Android开发对应模块,为了使得双方通信方便,特意封装了一个接口,可实现Android与Uni-app互相通讯。二、内容做完以下第一、第二部分,即可实现Android与uni-app互相通信,当然双方通信有不同方式,具体情况具体分析,我的采用的方案是写Android原生插件,在un</div>
                    </li>
                    <li><a href="/article/1938803367711141888.htm"
                           title="鸿蒙开发:一文了解桌面卡片" target="_blank">鸿蒙开发:一文了解桌面卡片</a>
                        <span class="text-muted"></span>

                        <div>前言本文基于Api13鸿蒙的桌面卡片功能,也就是服务卡片,和Android端的小部件以及iOS端的小组件功能是一样的,只是叫法不一样,都是将应用内比较核心的功能,或者用户关注度高的功能,通过触发桌面应用进行添加到服务卡片上,进而添加到桌面上,以此达到信息展示的及时性,相关功能直达应用内的便捷效果,可以说在用户体验上,是一个质的提升。触发方式也是十分的简单,无论你是Android、iOS还是Harm</div>
                    </li>
                    <li><a href="/article/1938801245347180544.htm"
                           title="微信小程序防录频截屏ios+android" target="_blank">微信小程序防录频截屏ios+android</a>
                        <span class="text-muted">Yannnnnm</span>
<a class="tag" taget="_blank" href="/search/ios/1.htm">ios</a><a class="tag" taget="_blank" href="/search/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F/1.htm">微信小程序</a><a class="tag" taget="_blank" href="/search/android/1.htm">android</a>
                        <div>ios截屏暂未解决安卓录频截屏代码可以写在onshow中//安卓防止截屏录屏if(/android/i.test(wx.getSystemInfoSync().system)&&wx.setVisualEffectOnCapture){wx.setVisualEffectOnCapture({visualEffect:'hidden',complete:function(res){//wx.sho</div>
                    </li>
                    <li><a href="/article/1938785616422563840.htm"
                           title="RK系列(RK3568) GPIO按键驱动 和Android key新值添加" target="_blank">RK系列(RK3568) GPIO按键驱动 和Android key新值添加</a>
                        <span class="text-muted">hmbbPdx_</span>
<a class="tag" taget="_blank" href="/search/RK%E9%A9%B1%E5%8A%A8%E5%BC%80%E5%8F%91/1.htm">RK驱动开发</a><a class="tag" taget="_blank" href="/search/Rk%E5%BC%80%E5%8F%91%28RK3568%29/1.htm">Rk开发(RK3568)</a><a class="tag" taget="_blank" href="/search/android/1.htm">android</a><a class="tag" taget="_blank" href="/search/%E9%A9%B1%E5%8A%A8%E5%BC%80%E5%8F%91/1.htm">驱动开发</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a>
                        <div>平台:Android12SOC:RK3568kernel:Linux-4.19首先按键驱动那块不用我们自己写,内核本身有支持可以查看kernel-4.19-driver/input/keyboard/gpio_keys.c我们先描述好设备树添加GPIO4-A0的按键gpio-keys{compatible="gpio-keys";#address-cells=;#size-cells=;autor</div>
                    </li>
                    <li><a href="/article/1938742508532068352.htm"
                           title="Android-Layout Inspector使用手册" target="_blank">Android-Layout Inspector使用手册</a>
                        <span class="text-muted">每次的天空</span>
<a class="tag" taget="_blank" href="/search/android/1.htm">android</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a>
                        <div>LayoutInspectorAndroidLayoutInspector是AndroidStudio中用于调试应用布局的工具启动方法:通过下载LayoutInspector插件,在“View-ToolWindows-LayoutInspector”或“Tools-LayoutInspector”启动。主要界面区域:ComponentTree:显示布局中视图的层次结构,帮助直观查看应用中的元素及其</div>
                    </li>
                    <li><a href="/article/1938736836469911552.htm"
                           title="数据库设计和功能需求分析------后台设计概述" target="_blank">数据库设计和功能需求分析------后台设计概述</a>
                        <span class="text-muted">qq_41490913</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%BA%93/1.htm">数据库</a>
                        <div>功能需求分析和数据库设计不论是Web开发还是Android开发,在设计后台的时候我们都要做的重要的事情不外乎两点:1.需求分析;2.数据库表格的设计。在进行这两项工作的过程中,第一项工作对第二项起着非常重要的作用,我们只有真正的搞清楚了业务需求以及业务逻辑,找到了功能模块之间在后台数据库关联的抽象模型,这样才能确定数据库应该有几张表,每张表有哪些字段,表与表之间该如何联系。需求分析与功能模块设计一</div>
                    </li>
                    <li><a href="/article/1938733053195120640.htm"
                           title="Android.mk" target="_blank">Android.mk</a>
                        <span class="text-muted">盼雨落,等风起</span>
<a class="tag" taget="_blank" href="/search/%E5%AE%89%E5%8D%93/1.htm">安卓</a><a class="tag" taget="_blank" href="/search/%E8%84%9A%E6%9C%AC%E6%96%87%E4%BB%B6/1.htm">脚本文件</a><a class="tag" taget="_blank" href="/search/android/1.htm">android</a>
                        <div>一、基础认知定位AndroidNDK构建系统的GNUMakefile片段,描述NDK项目结构可编译生成:APK、JAVA库、C/C++可执行程序、静态库(.a)、动态库(.so)兼容性:新源码逐渐转向Android.bp,但Android.mk仍被支持文件结构LOCAL_PATH:=$(callmy-dir)#必选:定义当前路径include$(CLEAR_VARS)#必选:清除变量(除LOCAL</div>
                    </li>
                    <li><a href="/article/1938693727472119808.htm"
                           title="九、buildroot系统 usb配置" target="_blank">九、buildroot系统 usb配置</a>
                        <span class="text-muted"></span>

                        <div>3.3、usb配置源码中kernel默认已经打开了相关的usb配置,只需要在buildroot中打开相关配置。1、基本功能类别简称功能描述ADB(AndroidDebugBridge)ADB是一种功能多样的命令行调试工具,可以实现文件传输,UnixShell登录等功能。UAC(USBAudioClass)UAC通过USB虚拟标准PCM接口给Host设备,实现Device和Host之间音频互传功能。</div>
                    </li>
                    <li><a href="/article/1938673693815271424.htm"
                           title="Android Studio Profiler:性能优化的超能侦探" target="_blank">Android Studio Profiler:性能优化的超能侦探</a>
                        <span class="text-muted">你一身傲骨怎能输</span>
<a class="tag" taget="_blank" href="/search/Android%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/1.htm">Android操作系统</a><a class="tag" taget="_blank" href="/search/android/1.htm">android</a><a class="tag" taget="_blank" href="/search/studio/1.htm">studio</a><a class="tag" taget="_blank" href="/search/%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96/1.htm">性能优化</a><a class="tag" taget="_blank" href="/search/android/1.htm">android</a>
                        <div>文章摘要AndroidStudioProfiler是开发者的"超级监工",通过可视化方式监测APP性能问题:CPU侦探:记录方法调用栈与耗时,定位卡顿根源,如同工厂摄像头追踪机器效率;内存侦探:监控对象分配与GC活动,揪出内存泄漏,像仓库管理员清点过期库存;网络侦探:分析请求速度与数据量,优化传输效率,堪比物流中心调度运输车辆。三大工具协同工作,帮助应用实现更流畅、稳定、高效的运行表现。(注:能耗</div>
                    </li>
                    <li><a href="/article/1938660079830102016.htm"
                           title="Linux Telephony开发中各组件关系及通信流程" target="_blank">Linux Telephony开发中各组件关系及通信流程</a>
                        <span class="text-muted">小米人儿</span>
<a class="tag" taget="_blank" href="/search/%E6%88%91%E7%9A%84%E5%8D%9A%E5%AE%A2/1.htm">我的博客</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a>
                        <div>好的,我们来梳理一下在Linux移动设备(尤其是早期Android和基于Linux的移动平台)Telephony开发中dbus,oFono,RIL,RILReference,Modem之间的关系、通信方式和设计目的。核心关系图(简化):[TelephonyApplications](e.g.,Dialer,Messaging)|v(D-Bus)[oFono]||(InternalPluginAPI</div>
                    </li>
                    <li><a href="/article/1938657684890906624.htm"
                           title="Android实时获取声音音量大小" target="_blank">Android实时获取声音音量大小</a>
                        <span class="text-muted">泓博</span>
<a class="tag" taget="_blank" href="/search/android/1.htm">android</a>
                        <div>使用AudioRecord实时获取音量创建一个AudioRecord实例并持续读取音频数据,计算音量大小。AudioRecord适用于需要原始音频数据的场景。privatevoidstartRecording(){intminBufferSize=AudioRecord.getMinBufferSize(SAMPLE_RATE,AudioFormat.CHANNEL_IN_MONO,AudioFo</div>
                    </li>
                    <li><a href="/article/1938657178500001792.htm"
                           title="Android 16系统源码_无障碍辅助(二)Android 的无障碍框架" target="_blank">Android 16系统源码_无障碍辅助(二)Android 的无障碍框架</a>
                        <span class="text-muted">AFinalStone</span>
<a class="tag" taget="_blank" href="/search/Framework12%E6%BA%90%E7%A0%81/1.htm">Framework12源码</a><a class="tag" taget="_blank" href="/search/android/1.htm">android</a>
                        <div>前言上一篇文章我们通过一个简单案例,初步认识了无障碍服务,本篇文章我们将会结合具体的系统源码来对无障碍服务进行一下深入分析。组件介绍核心组件Android无障碍框架(AccessibilityFramework)的源码位于AOSP(AndroidOpenSourceProject)中的frameworks/base/core/java/android/accessibilityservice/仓库</div>
                    </li>
                    <li><a href="/article/1938655918489137152.htm"
                           title="Pytorch模型安卓部署" target="_blank">Pytorch模型安卓部署</a>
                        <span class="text-muted">python&java</span>
<a class="tag" taget="_blank" href="/search/pytorch/1.htm">pytorch</a><a class="tag" taget="_blank" href="/search/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/1.htm">人工智能</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a>
                        <div>Pytorch是一种流行的深度学习框架,用于算法开发,而Android是一种广泛应用的操作系统,多应用于移动设备当中。目前多数的研究都是在于算法上,个人觉得把算法落地是一件很有意思的事情,因此本人准备分享一些模型落地的文章(后续可能分享微信小程序部署,PyQt部署以及exe打包,ncnn部署,tensorRT部署,MNN部署)。本篇文章主要分享Pytorch的Android端部署。看这篇文章的读者</div>
                    </li>
                    <li><a href="/article/1938609401032142848.htm"
                           title="GDPU移动应用开发(安卓)期末考试复习资料" target="_blank">GDPU移动应用开发(安卓)期末考试复习资料</a>
                        <span class="text-muted"></span>

                        <div>第一部分一、选择题应用的基本构建块是:A.ActivityB.FragmentC.ServiceD.Intent答案:A.Activity下列哪个不是AndroidManifest.xml文件的主要用途?A.声明应用权限B.声明应用组件C.定义应用的图标和名称D.编写应用的业务逻辑答案:D.编写应用的业务逻辑在Android中、用于存储持久化数据的SQLite数据库、默认存储在哪个目录下?A./s</div>
                    </li>
                    <li><a href="/article/1938597044486729728.htm"
                           title="自学Java怎么入门" target="_blank">自学Java怎么入门</a>
                        <span class="text-muted">Java鼠鼠吖</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a>
                        <div>自学Java其实没有想象中那么难,只要找对方法,循序渐进地学习,很快就能上手。下面我结合自己的经验,给你整理一条清晰的学习路径,咱们一步步来。一、先了解Java能做什么在开始之前,建议你先看看Java都能用在哪些地方。比如开发企业级系统、Android应用、大数据处理等等。这样你就能明白为什么要学它,也更有动力。Java最大的特点就是"一次编写,到处运行",这要归功于JVM虚拟机。二、准备好学习环</div>
                    </li>
                    <li><a href="/article/1938540185247608832.htm"
                           title="ubuntu系统共享桌面的使用和配置" target="_blank">ubuntu系统共享桌面的使用和配置</a>
                        <span class="text-muted">zfb132</span>
<a class="tag" taget="_blank" href="/search/Linux/1.htm">Linux</a><a class="tag" taget="_blank" href="/search/ubuntu/1.htm">ubuntu</a><a class="tag" taget="_blank" href="/search/remmina/1.htm">remmina</a><a class="tag" taget="_blank" href="/search/frp/1.htm">frp</a><a class="tag" taget="_blank" href="/search/%E5%85%B1%E4%BA%AB%E6%A1%8C%E9%9D%A2/1.htm">共享桌面</a>
                        <div>内容转载自我的博客文章目录1.ubuntu共享桌面2.局域网登录远程桌面2.1ubuntu使用remmina登录远程桌面2.2在windows登录远程桌面2.3Android使用RDClient登录远程桌面3.外网登录远程桌面3.1方法一3.2方法二4.安装xrdp实现多用户登录远程桌面1.ubuntu共享桌面在ubuntu桌面发行版打开屏幕共享功能,步骤如下:设置-->共享-->屏幕共享打开总开</div>
                    </li>
                    <li><a href="/article/1938535645798526976.htm"
                           title="微信小程序适配 iPhone 底部导航区域(safe area)的完整指南" target="_blank">微信小程序适配 iPhone 底部导航区域(safe area)的完整指南</a>
                        <span class="text-muted">爱宇阳</span>
<a class="tag" taget="_blank" href="/search/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F/1.htm">微信小程序</a><a class="tag" taget="_blank" href="/search/Vue/1.htm">Vue</a><a class="tag" taget="_blank" href="/search/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F/1.htm">微信小程序</a><a class="tag" taget="_blank" href="/search/iphone/1.htm">iphone</a><a class="tag" taget="_blank" href="/search/%E5%B0%8F%E7%A8%8B%E5%BA%8F/1.htm">小程序</a>
                        <div>解决吸底按钮被遮挡、iOS“小黑条”兼容问题,基于env()与constant()的CSS安全区域适配。一、问题背景从iPhoneX开始,iOS引入了底部的“Home指示条”(俗称“小黑条”),这导致页面底部元素若处理不当,容易出现:吸底按钮被遮挡;用户点击操作困难;安卓正常,iOS异常。二、目标实现页面底部元素(如按钮、工具栏等)在iOS刘海屏下不被遮挡,且Android、普通iOS设备兼容良好</div>
                    </li>
                    <li><a href="/article/1938532115515764736.htm"
                           title="Android github 快速实现多人协作" target="_blank">Android github 快速实现多人协作</a>
                        <span class="text-muted">weixin_34037977</span>
<a class="tag" taget="_blank" href="/search/%E7%A7%BB%E5%8A%A8%E5%BC%80%E5%8F%91/1.htm">移动开发</a>
                        <div>前言:最近要做github多人协作,也就是多人开发。搜索了一些资料,千篇一律,而且操作麻烦。今天就整理一下,github多人协作的简单实现方法。下面的教程不会出现:公钥、组织、team、pullrequest1、首先小张在github上创建一个仓库,比如叫做:GlideDemo2、小张开始邀请小王创建仓库后,然后开始添加小王了。注意在第三步的时候,要输入小王的github用户名。3、小王接收小张的</div>
                    </li>
                    <li><a href="/article/1938518249138352128.htm"
                           title="Python(一)实现一个爬取微信小程序数据的爬虫+工程化初步实践" target="_blank">Python(一)实现一个爬取微信小程序数据的爬虫+工程化初步实践</a>
                        <span class="text-muted">JackSparrow414</span>
<a class="tag" taget="_blank" href="/search/Python/1.htm">Python</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F/1.htm">微信小程序</a><a class="tag" taget="_blank" href="/search/%E7%88%AC%E8%99%AB/1.htm">爬虫</a><a class="tag" taget="_blank" href="/search/pip/1.htm">pip</a><a class="tag" taget="_blank" href="/search/selenium/1.htm">selenium</a><a class="tag" taget="_blank" href="/search/%E7%BD%91%E7%BB%9C%E7%88%AC%E8%99%AB/1.htm">网络爬虫</a>
                        <div>文章目录前言用Charles抓包iOS微信小程序在Mac端和iOS端安装Charles自签名证书Mac端iOS端能抓到Safari浏览器的包但是抓不到微信小程序的包直接在iOS上抓包的App如何抓取Android7.0以上/HarmonyOS微信小程序包Python项目工程化pip切换为国内镜像源工程化参考脚手架Python虚拟环境实现爬虫动态IP确保代理服务器的延迟够低设置User-Agent发</div>
                    </li>
                    <li><a href="/article/1938512699419848704.htm"
                           title="配置Cuttlefish 虚拟 Android 设备" target="_blank">配置Cuttlefish 虚拟 Android 设备</a>
                        <span class="text-muted">liuzl_2010</span>
<a class="tag" taget="_blank" href="/search/android/1.htm">android</a><a class="tag" taget="_blank" href="/search/android/1.htm">android</a>
                        <div>google参考资料:https://source.android.com/docs/setup/start?hl=zh-cnhttps://source.android.com/docs/devices/cuttlefish/get-started?hl=zh-cnCuttlefish开始验证KVM可用性Cuttlefish是一种虚拟设备,依赖于宿主机上可用的虚拟化。在宿主机上的终端中,确保可以</div>
                    </li>
                    <li><a href="/article/1938511187943682048.htm"
                           title="Android 音乐播放器实现底部播放器、全屏播放器一体化(Fragment+ BottomSheet实现)" target="_blank">Android 音乐播放器实现底部播放器、全屏播放器一体化(Fragment+ BottomSheet实现)</a>
                        <span class="text-muted"></span>

                        <div>一个基础的一体化播放控制器,用于提升用户体验,减少界面切换带来的不便,以及提高开发效率和性能。依赖添加implementation'com.github.bumptech.glide:glide:4.16.0'implementation'androidx.cardview:cardview:1.0.0'最终效果,底部控制器、过渡动画、全屏控制器一整体思路项目已上传至github,musicpla</div>
                    </li>
                    <li><a href="/article/1938510684111302656.htm"
                           title="Cuttlefish Android环境搭建" target="_blank">Cuttlefish Android环境搭建</a>
                        <span class="text-muted">weixin_45670959</span>
<a class="tag" taget="_blank" href="/search/android/1.htm">android</a>
                        <div>如何使用Cuttlefish来启动安卓AAOS14Cuttlefish的介绍Cuttlefish是一种可配置的虚拟Android设备,既可以远程运行(使用第三方云产品,如GoogleCloudEngine),又可以在本地运行(在Linuxx86和ARM64计算机上)。Cuttlefish的用途使平台和应用开发者不再依赖于物理硬件来开发和验证代码更改。能够并发执行测试,实现高保真度且入门成本较低。提</div>
                    </li>
                    <li><a href="/article/1938509550902636544.htm"
                           title="c语言opencv所用库函数,Py之cv2:cv2库(OpenCV,opencv-python)的简介、安装、使用方法(常见函数、方法等)最强详细攻略..." target="_blank">c语言opencv所用库函数,Py之cv2:cv2库(OpenCV,opencv-python)的简介、安装、使用方法(常见函数、方法等)最强详细攻略...</a>
                        <span class="text-muted">weixin_39729272</span>
<a class="tag" taget="_blank" href="/search/c%E8%AF%AD%E8%A8%80opencv%E6%89%80%E7%94%A8%E5%BA%93%E5%87%BD%E6%95%B0/1.htm">c语言opencv所用库函数</a>
                        <div>##关于OpenCV简介##OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,可以运行在Linux、Windows、Android和MacOS操作系统上。它轻量级而且高效——由一系列C函数和少量C++类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。OpenCV用C++语言编写,它的主要接口也是C++语言,但是依然保留</div>
                    </li>
                    <li><a href="/article/1938502496867643392.htm"
                           title="如何将AndroidStudio编译出来的APP设置为系统应用" target="_blank">如何将AndroidStudio编译出来的APP设置为系统应用</a>
                        <span class="text-muted">小馬佩德罗</span>
<a class="tag" taget="_blank" href="/search/Android%E7%B3%BB%E7%BB%9F/1.htm">Android系统</a>
                        <div>如何将AndroidStudio编译出来的APP设置为系统应用声明1在AndroidStudio中采用platform.pk8、platform.x509.pem生成的签名编译2讲AndroidStudio编译出的apk放入Android系统源码中和系统一起编译声明前阶段需要在开发一个system权限的APP,整理了两种方法,在此做个整理总结。两种方法的前提都是要有Android系统源码,或And</div>
                    </li>
                    <li><a href="/article/1938457873944211456.htm"
                           title="Android 控件 - gravity 属性与 layout_gravity 属性" target="_blank">Android 控件 - gravity 属性与 layout_gravity 属性</a>
                        <span class="text-muted">我命由我12345</span>
<a class="tag" taget="_blank" href="/search/Android/1.htm">Android</a><a class="tag" taget="_blank" href="/search/-/1.htm">-</a><a class="tag" taget="_blank" href="/search/%E7%AE%80%E5%8C%96%E7%BC%96%E7%A8%8B/1.htm">简化编程</a><a class="tag" taget="_blank" href="/search/android/1.htm">android</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/java-ee/1.htm">java-ee</a><a class="tag" taget="_blank" href="/search/%E5%AE%89%E5%8D%93/1.htm">安卓</a><a class="tag" taget="_blank" href="/search/android-studio/1.htm">android-studio</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a><a class="tag" taget="_blank" href="/search/android/1.htm">android</a><a class="tag" taget="_blank" href="/search/studio/1.htm">studio</a>
                        <div>一、gravity属性1、基本介绍gravity属性用于控制View内部的内容的对齐方式作用对象是View内部的内容,例如,文本、子View等常用值说明left水平方向左对齐right水平方向右对齐start水平方向左对齐(RTL)end水平方向右对齐(RTL)top垂直方向顶部对齐bottom垂直方向底部对齐center_horizontal水平方向居中center_vertical垂直方向居中</div>
                    </li>
                    <li><a href="/article/1938453964743831552.htm"
                           title="Android杂谈(一):悬浮球" target="_blank">Android杂谈(一):悬浮球</a>
                        <span class="text-muted">人生游戏牛马NPC1号</span>
<a class="tag" taget="_blank" href="/search/android/1.htm">android</a><a class="tag" taget="_blank" href="/search/kotlin/1.htm">kotlin</a>
                        <div>目录1.概述1.1什么是悬浮球(FloatingBall)1.1.1悬浮球的定义1.1.2悬浮球的基本概念1.1.3悬浮球的常见作用1.2悬浮球的应用场景与优势1.2.1悬浮球的常见应用场景1.2.2悬浮球带来的便利与优势悬浮球带来的便利与优势1.2.3设计建议1.3Android中悬浮球的实现方式简介2.悬浮球基础实现2.1创建悬浮球布局(XML设计)2.2悬浮球的显示与隐藏控制2.3悬浮球拖拽</div>
                    </li>
                                <li><a href="/article/111.htm"
                                       title="JAVA基础" target="_blank">JAVA基础</a>
                                    <span class="text-muted">灵静志远</span>
<a class="tag" taget="_blank" href="/search/%E4%BD%8D%E8%BF%90%E7%AE%97/1.htm">位运算</a><a class="tag" taget="_blank" href="/search/%E5%8A%A0%E8%BD%BD/1.htm">加载</a><a class="tag" taget="_blank" href="/search/Date/1.htm">Date</a><a class="tag" taget="_blank" href="/search/%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%B1%A0/1.htm">字符串池</a><a class="tag" taget="_blank" href="/search/%E8%A6%86%E7%9B%96/1.htm">覆盖</a>
                                    <div>一、类的初始化顺序 
1 (静态变量,静态代码块)-->(变量,初始化块)--> 构造器 
 同一括号里的,根据它们在程序中的顺序来决定。上面所述是同一类中。如果是继承的情况,那就在父类到子类交替初始化。 
 
二、String 
1 String a = "abc"; 
 JAVA虚拟机首先在字符串池中查找是否已经存在了值为"abc"的对象,根</div>
                                </li>
                                <li><a href="/article/238.htm"
                                       title="keepalived实现redis主从高可用" target="_blank">keepalived实现redis主从高可用</a>
                                    <span class="text-muted">bylijinnan</span>
<a class="tag" taget="_blank" href="/search/redis/1.htm">redis</a>
                                    <div>方案说明 
 
两台机器(称为A和B),以统一的VIP对外提供服务 
1.正常情况下,A和B都启动,B会把A的数据同步过来(B is slave of A) 
2.当A挂了后,VIP漂移到B;B的keepalived 通知redis 执行:slaveof no one,由B提供服务 
3.当A起来后,VIP不切换,仍在B上面;而A的keepalived 通知redis 执行slaveof B,开始</div>
                                </li>
                                <li><a href="/article/365.htm"
                                       title="java文件操作大全" target="_blank">java文件操作大全</a>
                                    <span class="text-muted">0624chenhong</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a>
                                    <div>最近在博客园看到一篇比较全面的文件操作文章,转过来留着。 
 
http://www.cnblogs.com/zhuocheng/archive/2011/12/12/2285290.html 
 
转自http://blog.sina.com.cn/s/blog_4a9f789a0100ik3p.html 
 
 
一.获得控制台用户输入的信息 
 
   &nbs</div>
                                </li>
                                <li><a href="/article/492.htm"
                                       title="android学习任务" target="_blank">android学习任务</a>
                                    <span class="text-muted">不懂事的小屁孩</span>
<a class="tag" taget="_blank" href="/search/%E5%B7%A5%E4%BD%9C/1.htm">工作</a>
                                    <div>任务 
完成情况   搞清楚带箭头的pupupwindows和不带的使用 已完成   熟练使用pupupwindows和alertdialog,并搞清楚两者的区别 已完成   熟练使用android的线程handler,并敲示例代码 进行中   了解游戏2048的流程,并完成其代码工作 进行中-差几个actionbar   研究一下android的动画效果,写一个实例 已完成   复习fragem</div>
                                </li>
                                <li><a href="/article/619.htm"
                                       title="zoom.js" target="_blank">zoom.js</a>
                                    <span class="text-muted">换个号韩国红果果</span>
<a class="tag" taget="_blank" href="/search/oom/1.htm">oom</a>
                                    <div>它的基于bootstrap 的 
https://raw.github.com/twbs/bootstrap/master/js/transition.js  transition.js模块引用顺序 
 

<link rel="stylesheet" href="style/zoom.css">
<script src=&q</div>
                                </li>
                                <li><a href="/article/746.htm"
                                       title="详解Oracle云操作系统Solaris 11.2" target="_blank">详解Oracle云操作系统Solaris 11.2</a>
                                    <span class="text-muted">蓝儿唯美</span>
<a class="tag" taget="_blank" href="/search/Solaris/1.htm">Solaris</a>
                                    <div>当Oracle发布Solaris 11时,它将自己的操作系统称为第一个面向云的操作系统。Oracle在发布Solaris 11.2时继续它以云为中心的基调。但是,这些说法没有告诉我们为什么Solaris是配得上云的。幸好,我们不需要等太久。Solaris11.2有4个重要的技术可以在一个有效的云实现中发挥重要作用:OpenStack、内核域、统一存档(UA)和弹性虚拟交换(EVS)。  </div>
                                </li>
                                <li><a href="/article/873.htm"
                                       title="spring学习——springmvc(一)" target="_blank">spring学习——springmvc(一)</a>
                                    <span class="text-muted">a-john</span>
<a class="tag" taget="_blank" href="/search/springMVC/1.htm">springMVC</a>
                                    <div>Spring MVC基于模型-视图-控制器(Model-View-Controller,MVC)实现,能够帮助我们构建像Spring框架那样灵活和松耦合的Web应用程序。 
  
1,跟踪Spring MVC的请求 
请求的第一站是Spring的DispatcherServlet。与大多数基于Java的Web框架一样,Spring MVC所有的请求都会通过一个前端控制器Servlet。前</div>
                                </li>
                                <li><a href="/article/1000.htm"
                                       title="hdu4342 History repeat itself-------多校联合五" target="_blank">hdu4342 History repeat itself-------多校联合五</a>
                                    <span class="text-muted">aijuans</span>
<a class="tag" taget="_blank" href="/search/%E6%95%B0%E8%AE%BA/1.htm">数论</a>
                                    <div>水题就不多说什么了。 
#include<iostream>#include<cstdlib>#include<stdio.h>#define ll __int64using namespace std;int main(){    int t;    ll n;    scanf("%d",&t);    while(t--)   </div>
                                </li>
                                <li><a href="/article/1127.htm"
                                       title="EJB和javabean的区别" target="_blank">EJB和javabean的区别</a>
                                    <span class="text-muted">asia007</span>
<a class="tag" taget="_blank" href="/search/bean/1.htm">bean</a><a class="tag" taget="_blank" href="/search/ejb/1.htm">ejb</a>
                                    <div>EJB不是一般的JavaBean,EJB是企业级JavaBean,EJB一共分为3种,实体Bean,消息Bean,会话Bean,书写EJB是需要遵循一定的规范的,具体规范你可以参考相关的资料.另外,要运行EJB,你需要相应的EJB容器,比如Weblogic,Jboss等,而JavaBean不需要,只需要安装Tomcat就可以了 
  
1.EJB用于服务端应用开发, 而JavaBeans</div>
                                </li>
                                <li><a href="/article/1254.htm"
                                       title="Struts的action和Result总结" target="_blank">Struts的action和Result总结</a>
                                    <span class="text-muted">百合不是茶</span>
<a class="tag" taget="_blank" href="/search/struts/1.htm">struts</a><a class="tag" taget="_blank" href="/search/Action%E9%85%8D%E7%BD%AE/1.htm">Action配置</a><a class="tag" taget="_blank" href="/search/Result%E9%85%8D%E7%BD%AE/1.htm">Result配置</a>
                                    <div>  
  
一:Action的配置详解: 
     下面是一个Struts中一个空的Struts.xml的配置文件 
    
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
	&quo</div>
                                </li>
                                <li><a href="/article/1381.htm"
                                       title="如何带好自已的团队" target="_blank">如何带好自已的团队</a>
                                    <span class="text-muted">bijian1013</span>
<a class="tag" taget="_blank" href="/search/%E9%A1%B9%E7%9B%AE%E7%AE%A1%E7%90%86/1.htm">项目管理</a><a class="tag" taget="_blank" href="/search/%E5%9B%A2%E9%98%9F%E7%AE%A1%E7%90%86/1.htm">团队管理</a><a class="tag" taget="_blank" href="/search/%E5%9B%A2%E9%98%9F/1.htm">团队</a>
                                    <div>在网上看到博客" 
怎么才能让团队成员好好干活"的评论,觉得写的比较好。   原文如下:   我做团队管理有几年了吧,我和你分享一下我认为带好团队的几点: 
1.诚信 
        对团队内成员,无论是技术研究、交流、问题探讨,要尽可能的保持一种诚信的态度,用心去做好,你的团队会感觉得到。   2.努力提</div>
                                </li>
                                <li><a href="/article/1508.htm"
                                       title="Java代码混淆工具" target="_blank">Java代码混淆工具</a>
                                    <span class="text-muted">sunjing</span>
<a class="tag" taget="_blank" href="/search/ProGuard/1.htm">ProGuard</a>
                                    <div>Open Source Obfuscators 
ProGuard 
http://java-source.net/open-source/obfuscators/proguardProGuard is a free Java class file shrinker and obfuscator. It can detect and remove unused classes, fields, m</div>
                                </li>
                                <li><a href="/article/1635.htm"
                                       title="【Redis三】基于Redis sentinel的自动failover主从复制" target="_blank">【Redis三】基于Redis sentinel的自动failover主从复制</a>
                                    <span class="text-muted">bit1129</span>
<a class="tag" taget="_blank" href="/search/redis/1.htm">redis</a>
                                    <div>在第二篇中使用2.8.17搭建了主从复制,但是它存在Master单点问题,为了解决这个问题,Redis从2.6开始引入sentinel,用于监控和管理Redis的主从复制环境,进行自动failover,即Master挂了后,sentinel自动从从服务器选出一个Master使主从复制集群仍然可以工作,如果Master醒来再次加入集群,只能以从服务器的形式工作。 
  什么是Sentine</div>
                                </li>
                                <li><a href="/article/1762.htm"
                                       title="使用代理实现Hibernate Dao层自动事务" target="_blank">使用代理实现Hibernate Dao层自动事务</a>
                                    <span class="text-muted">白糖_</span>
<a class="tag" taget="_blank" href="/search/DAO/1.htm">DAO</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/AOP/1.htm">AOP</a><a class="tag" taget="_blank" href="/search/%E6%A1%86%E6%9E%B6/1.htm">框架</a><a class="tag" taget="_blank" href="/search/Hibernate/1.htm">Hibernate</a>
                                    <div>都说spring利用AOP实现自动事务处理机制非常好,但在只有hibernate这个框架情况下,我们开启session、管理事务就往往很麻烦。 
public void save(Object obj){
		Session session = this.getSession();
		Transaction tran = session.beginTransaction();
		try </div>
                                </li>
                                <li><a href="/article/1889.htm"
                                       title="maven3实战读书笔记" target="_blank">maven3实战读书笔记</a>
                                    <span class="text-muted">braveCS</span>
<a class="tag" taget="_blank" href="/search/maven3/1.htm">maven3</a>
                                    <div>Maven简介 
是什么? 
Is a software project management and comprehension tool.项目管理工具 
是基于POM概念(工程对象模型) 
[设计重复、编码重复、文档重复、构建重复,maven最大化消除了构建的重复] 
[与XP:简单、交流与反馈;测试驱动开发、十分钟构建、持续集成、富有信息的工作区] 
  
  
功能: </div>
                                </li>
                                <li><a href="/article/2016.htm"
                                       title="编程之美-子数组的最大乘积" target="_blank">编程之美-子数组的最大乘积</a>
                                    <span class="text-muted">bylijinnan</span>
<a class="tag" taget="_blank" href="/search/%E7%BC%96%E7%A8%8B%E4%B9%8B%E7%BE%8E/1.htm">编程之美</a>
                                    <div>

public class MaxProduct {

	/**
	 * 编程之美 子数组的最大乘积
	 * 题目: 给定一个长度为N的整数数组,只允许使用乘法,不能用除法,计算任意N-1个数的组合中乘积中最大的一组,并写出算法的时间复杂度。
	 * 以下程序对应书上两种方法,求得“乘积中最大的一组”的乘积——都是有溢出的可能的。
	 * 但按题目的意思,是要求得这个子数组,而不</div>
                                </li>
                                <li><a href="/article/2143.htm"
                                       title="读书笔记-2" target="_blank">读书笔记-2</a>
                                    <span class="text-muted">chengxuyuancsdn</span>
<a class="tag" taget="_blank" href="/search/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/1.htm">读书笔记</a>
                                    <div>1、反射 
2、oracle年-月-日 时-分-秒 
3、oracle创建有参、无参函数 
4、oracle行转列 
5、Struts2拦截器 
6、Filter过滤器(web.xml) 
 
 
1、反射
(1)检查类的结构
在java.lang.reflect包里有3个类Field,Method,Constructor分别用于描述类的域、方法和构造器。
2、oracle年月日时分秒
s</div>
                                </li>
                                <li><a href="/article/2270.htm"
                                       title="[求学与房地产]慎重选择IT培训学校" target="_blank">[求学与房地产]慎重选择IT培训学校</a>
                                    <span class="text-muted">comsci</span>
<a class="tag" taget="_blank" href="/search/it/1.htm">it</a>
                                    <div>      关于培训学校的教学和教师的问题,我们就不讨论了,我主要关心的是这个问题 
 
      培训学校的教学楼和宿舍的环境和稳定性问题 
 
      我们大家都知道,房子是一个比较昂贵的东西,特别是那种能够当教室的房子... 
 
&nb</div>
                                </li>
                                <li><a href="/article/2397.htm"
                                       title="RMAN配置中通道(CHANNEL)相关参数 PARALLELISM 、FILESPERSET的关系" target="_blank">RMAN配置中通道(CHANNEL)相关参数 PARALLELISM 、FILESPERSET的关系</a>
                                    <span class="text-muted">daizj</span>
<a class="tag" taget="_blank" href="/search/oracle/1.htm">oracle</a><a class="tag" taget="_blank" href="/search/rman/1.htm">rman</a><a class="tag" taget="_blank" href="/search/filesperset/1.htm">filesperset</a><a class="tag" taget="_blank" href="/search/PARALLELISM/1.htm">PARALLELISM</a>
                                    <div>RMAN配置中通道(CHANNEL)相关参数 PARALLELISM 、FILESPERSET的关系 转 
 
PARALLELISM --- 
 
我们还可以通过parallelism参数来指定同时"自动"创建多少个通道: 
RMAN > configure device type disk parallelism 3 ; 
表示启动三个通道,可以加快备份恢复的速度。 </div>
                                </li>
                                <li><a href="/article/2524.htm"
                                       title="简单排序:冒泡排序" target="_blank">简单排序:冒泡排序</a>
                                    <span class="text-muted">dieslrae</span>
<a class="tag" taget="_blank" href="/search/%E5%86%92%E6%B3%A1%E6%8E%92%E5%BA%8F/1.htm">冒泡排序</a>
                                    <div>
    public void bubbleSort(int[] array){
        for(int i=1;i<array.length;i++){
            for(int k=0;k<array.length-i;k++){
                if(array[k] > array[k+1]){
             </div>
                                </li>
                                <li><a href="/article/2651.htm"
                                       title="初二上学期难记单词三" target="_blank">初二上学期难记单词三</a>
                                    <span class="text-muted">dcj3sjt126com</span>
<a class="tag" taget="_blank" href="/search/sciet/1.htm">sciet</a>
                                    <div>concert 音乐会 
tonight 今晚 
famous 有名的;著名的 
song 歌曲 
thousand 千 
accident 事故;灾难 
careless 粗心的,大意的 
break 折断;断裂;破碎 
heart 心(脏) 
happen  偶尔发生,碰巧 
tourist 旅游者;观光者 
science (自然)科学 
marry 结婚 
subject 题目;</div>
                                </li>
                                <li><a href="/article/2778.htm"
                                       title="I.安装Memcahce 1. 安装依赖包libevent Memcache需要安装libevent,所以安装前可能需要执行 Shell代码 收藏代码" target="_blank">I.安装Memcahce 1. 安装依赖包libevent Memcache需要安装libevent,所以安装前可能需要执行 Shell代码 收藏代码</a>
                                    <span class="text-muted">dcj3sjt126com</span>
<a class="tag" taget="_blank" href="/search/redis/1.htm">redis</a>
                                    <div>wget http://download.redis.io/redis-stable.tar.gz 
tar xvzf redis-stable.tar.gz 
cd redis-stable 
make 
  
前面3步应该没有问题,主要的问题是执行make的时候,出现了异常。 
异常一: 
make[2]: cc: Command not found 
异常原因:没有安装g</div>
                                </li>
                                <li><a href="/article/2905.htm"
                                       title="并发容器" target="_blank">并发容器</a>
                                    <span class="text-muted">shuizhaosi888</span>
<a class="tag" taget="_blank" href="/search/%E5%B9%B6%E5%8F%91%E5%AE%B9%E5%99%A8/1.htm">并发容器</a>
                                    <div>   通过并发容器来改善同步容器的性能,同步容器将所有对容器状态的访问都串行化,来实现线程安全,这种方式严重降低并发性,当多个线程访问时,吞吐量严重降低。 
   并发容器ConcurrentHashMap 
      替代同步基于散列的Map,通过Lock控制。 
  &nb</div>
                                </li>
                                <li><a href="/article/3032.htm"
                                       title="Spring Security(12)——Remember-Me功能" target="_blank">Spring Security(12)——Remember-Me功能</a>
                                    <span class="text-muted">234390216</span>
<a class="tag" taget="_blank" href="/search/Spring+Security/1.htm">Spring Security</a><a class="tag" taget="_blank" href="/search/Remember+Me/1.htm">Remember Me</a><a class="tag" taget="_blank" href="/search/%E8%AE%B0%E4%BD%8F%E6%88%91/1.htm">记住我</a>
                                    <div>Remember-Me功能 
  
目录 
  
1.1     概述 
1.2     基于简单加密token的方法 
1.3     基于持久化token的方法 
1.4     Remember-Me相关接口和实现</div>
                                </li>
                                <li><a href="/article/3159.htm"
                                       title="位运算" target="_blank">位运算</a>
                                    <span class="text-muted">焦志广</span>
<a class="tag" taget="_blank" href="/search/%E4%BD%8D%E8%BF%90%E7%AE%97/1.htm">位运算</a>
                                    <div>
一、位运算符C语言提供了六种位运算符: 
 
& 按位与 
| 按位或 
^ 按位异或 
~ 取反 
<< 左移 
>> 右移 
 
 

1. 按位与运算 按位与运算符"&"是双目运算符。其功能是参与运算的两数各对应的二进位相与。只有对应的两个二进位均为1时,结果位才为1 ,否则为0。参与运算的数以补码方式出现。 
 
例如:9&am</div>
                                </li>
                                <li><a href="/article/3286.htm"
                                       title="nodejs 数据库连接 mongodb mysql" target="_blank">nodejs 数据库连接 mongodb mysql</a>
                                    <span class="text-muted">liguangsong</span>
<a class="tag" taget="_blank" href="/search/mongodb/1.htm">mongodb</a><a class="tag" taget="_blank" href="/search/mysql/1.htm">mysql</a><a class="tag" taget="_blank" href="/search/node/1.htm">node</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%BA%93%E8%BF%9E%E6%8E%A5/1.htm">数据库连接</a>
                                    <div>1.mysql 连接 
   package.json中dependencies加入 
  
  
"mysql":"~2.7.0" 
   执行 npm install 
  
   在config 下创建文件 database.js 
    
</div>
                                </li>
                                <li><a href="/article/3413.htm"
                                       title="java动态编译" target="_blank">java动态编译</a>
                                    <span class="text-muted">olive6615</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/HotSpot/1.htm">HotSpot</a><a class="tag" taget="_blank" href="/search/jvm/1.htm">jvm</a><a class="tag" taget="_blank" href="/search/%E5%8A%A8%E6%80%81%E7%BC%96%E8%AF%91/1.htm">动态编译</a>
                                    <div>    在HotSpot虚拟机中,有两个技术是至关重要的,即动态编译(Dynamic compilation)和Profiling。 
    HotSpot是如何动态编译Javad的bytecode呢?Java bytecode是以解释方式被load到虚拟机的。HotSpot里有一个运行监视器,即Profile Monitor,专门监视</div>
                                </li>
                                <li><a href="/article/3540.htm"
                                       title="Storm0.9.5的集群部署配置优化" target="_blank">Storm0.9.5的集群部署配置优化</a>
                                    <span class="text-muted">roadrunners</span>
<a class="tag" taget="_blank" href="/search/%E4%BC%98%E5%8C%96/1.htm">优化</a><a class="tag" taget="_blank" href="/search/storm.yaml/1.htm">storm.yaml</a>
                                    <div>nimbus结点配置(storm.yaml)信息: 
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional inf</div>
                                </li>
                                <li><a href="/article/3667.htm"
                                       title="101个MySQL 的调节和优化的提示" target="_blank">101个MySQL 的调节和优化的提示</a>
                                    <span class="text-muted">tomcat_oracle</span>
<a class="tag" taget="_blank" href="/search/mysql/1.htm">mysql</a>
                                    <div> 1. 拥有足够的物理内存来把整个InnoDB文件加载到内存中——在内存中访问文件时的速度要比在硬盘中访问时快的多。     2. 不惜一切代价避免使用Swap交换分区 – 交换时是从硬盘读取的,它的速度很慢。     3. 使用电池供电的RAM(注:RAM即随机存储器)。     4. 使用高级的RAID(注:Redundant Arrays of Inexpensive Disks,即磁盘阵列</div>
                                </li>
                                <li><a href="/article/3794.htm"
                                       title="zoj 3829 Known Notation(贪心)" target="_blank">zoj 3829 Known Notation(贪心)</a>
                                    <span class="text-muted">阿尔萨斯</span>
<a class="tag" taget="_blank" href="/search/ZOJ/1.htm">ZOJ</a>
                                    <div> 题目链接:zoj 3829 Known Notation 
 题目大意:给定一个不完整的后缀表达式,要求有2种不同操作,用尽量少的操作使得表达式完整。 
 解题思路:贪心,数字的个数要要保证比∗的个数多1,不够的话优先补在开头是最优的。然后遍历一遍字符串,碰到数字+1,碰到∗-1,保证数字的个数大于等1,如果不够减的话,可以和最后面的一个数字交换位置(用栈维护十分方便),因为添加和交换代价都是1</div>
                                </li>
                </ul>
            </div>
        </div>
    </div>

<div>
    <div class="container">
        <div class="indexes">
            <strong>按字母分类:</strong>
            <a href="/tags/A/1.htm" target="_blank">A</a><a href="/tags/B/1.htm" target="_blank">B</a><a href="/tags/C/1.htm" target="_blank">C</a><a
                href="/tags/D/1.htm" target="_blank">D</a><a href="/tags/E/1.htm" target="_blank">E</a><a href="/tags/F/1.htm" target="_blank">F</a><a
                href="/tags/G/1.htm" target="_blank">G</a><a href="/tags/H/1.htm" target="_blank">H</a><a href="/tags/I/1.htm" target="_blank">I</a><a
                href="/tags/J/1.htm" target="_blank">J</a><a href="/tags/K/1.htm" target="_blank">K</a><a href="/tags/L/1.htm" target="_blank">L</a><a
                href="/tags/M/1.htm" target="_blank">M</a><a href="/tags/N/1.htm" target="_blank">N</a><a href="/tags/O/1.htm" target="_blank">O</a><a
                href="/tags/P/1.htm" target="_blank">P</a><a href="/tags/Q/1.htm" target="_blank">Q</a><a href="/tags/R/1.htm" target="_blank">R</a><a
                href="/tags/S/1.htm" target="_blank">S</a><a href="/tags/T/1.htm" target="_blank">T</a><a href="/tags/U/1.htm" target="_blank">U</a><a
                href="/tags/V/1.htm" target="_blank">V</a><a href="/tags/W/1.htm" target="_blank">W</a><a href="/tags/X/1.htm" target="_blank">X</a><a
                href="/tags/Y/1.htm" target="_blank">Y</a><a href="/tags/Z/1.htm" target="_blank">Z</a><a href="/tags/0/1.htm" target="_blank">其他</a>
        </div>
    </div>
</div>
<footer id="footer" class="mb30 mt30">
    <div class="container">
        <div class="footBglm">
            <a target="_blank" href="/">首页</a> -
            <a target="_blank" href="/custom/about.htm">关于我们</a> -
            <a target="_blank" href="/search/Java/1.htm">站内搜索</a> -
            <a target="_blank" href="/sitemap.txt">Sitemap</a> -
            <a target="_blank" href="/custom/delete.htm">侵权投诉</a>
        </div>
        <div class="copyright">版权所有 IT知识库 CopyRight © 2000-2050 E-COM-NET.COM , All Rights Reserved.
<!--            <a href="https://beian.miit.gov.cn/" rel="nofollow" target="_blank">京ICP备09083238号</a><br>-->
        </div>
    </div>
</footer>
<!-- 代码高亮 -->
<script type="text/javascript" src="/static/syntaxhighlighter/scripts/shCore.js"></script>
<script type="text/javascript" src="/static/syntaxhighlighter/scripts/shLegacy.js"></script>
<script type="text/javascript" src="/static/syntaxhighlighter/scripts/shAutoloader.js"></script>
<link type="text/css" rel="stylesheet" href="/static/syntaxhighlighter/styles/shCoreDefault.css"/>
<script type="text/javascript" src="/static/syntaxhighlighter/src/my_start_1.js"></script>





</body>

</html>