WebView加载html标签中文乱码解决办法

 更新时间:2016年9月20日 19:52  点击:2035
本文章为各位介绍一篇关于WebView加载html标签中文乱码解决办法了,如果你碰到这类问题可以和小编一起来看看吧,具体的操作如下所示。

方法1:

String html="<p>我是测试用的标签</p>";
webView.loadData(html, "text/html", "utf-8");
效果如下:

lALOCsTfs80FAM0C0A_720_1280

 

啊嘞。乱码了。。试试下面的方法

方法2:

 String html="<p>我是测试用的标签</p>";
// webView.loadData(html, "text/html", "utf-8");
 webView.loadDataWithBaseURL(null, html, "text/html", "utf-8", null);
效果如下:

lALOCsUyIc0FAM0C0A_720_1280

可以了,完美。。。。

本文章为各位介绍一篇关于获取手机的屏幕宽高,density值,px 宽高,dp 的宽高,及px 和dp互转的例子,希望例子能够对大家有帮助。

直接贴代码

tvModel.setText(android.os.Build.MODEL);//手机型号

// 获取屏幕密度(方法1)
int screenWidth1 = getActivity().getWindowManager().getDefaultDisplay().getWidth();       // 屏幕宽(像素,如:480px)
int screenHeight1 = getActivity().getWindowManager().getDefaultDisplay().getHeight();      // 屏幕高(像素,如:800p)

tvScreenHeight1.setText(screenHeight1 + " px");
tvScreenWidth1.setText(screenWidth1 + " px");


// 获取屏幕密度(方法2)
DisplayMetrics dm2 = getResources().getDisplayMetrics();

float density = dm2.density;        // 屏幕密度(像素比例:0.75/1.0/1.5/2.0)
int densityDPI = dm2.densityDpi;     // 屏幕密度(每寸像素:120/160/240/320)
float xdpi = dm2.xdpi;
float ydpi = dm2.ydpi;

int screenWidth2 = dm2.widthPixels;      // 屏幕宽(像素,如:480px)
int screenHeight2 = dm2.heightPixels;     // 屏幕高(像素,如:800px)

tvScreenHeight2.setText(screenHeight2 + " px");
tvScreenWidth2.setText(screenWidth2 + " px");
tvScreenDensity2.setText(density + "");
tvScreenDensityDPI2.setText(densityDPI + "");

// 获取屏幕密度(方法3)
DisplayMetrics dm3 = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm3);

density = dm3.density;      // 屏幕密度(像素比例:0.75/1.0/1.5/2.0)
densityDPI = dm3.densityDpi;     // 屏幕密度(每寸像素:120/160/240/320)
xdpi = dm3.xdpi;
ydpi = dm3.ydpi;

tvScreenDensity3.setText(density + "");
tvScreenDensityDPI3.setText(densityDPI + "");

int screenWidth3 = dm3.widthPixels;          // 屏幕宽(px,如:480px)
int screenHeight3 = dm3.heightPixels;        // 屏幕高(px,如:800px)

tvScreenHeight3.setText(screenHeight3 + " px");
tvScreenWidth3.setText(screenWidth3 + " px");

float screenWidthDip = (dm3.widthPixels / density);    // 屏幕宽(dip,如:320dip)
float screenHeightDip = (dm3.heightPixels / density);   // 屏幕宽(dip,如:533dip)

tvScreenHeight4.setText(screenHeightDip + " dip");
tvScreenWidth4.setText(screenWidthDip + " dip");

本文章来为各位介绍一篇安卓开发教程了这篇教程主要介绍的是关于仿华为ViewPager指示器的一个例子与代码,具体的如下所示。
***本文纯手打,转载注明出处***

 

先看一下效果图:华为荣耀6的主题界面:

 

22 11

 

注意标题下的小圆点,本博客就是为了完成它.

 

思路:

 

布局方面:

 

上方一个LinearLayout,下面是一个ViewPager

 

功能方面:

 

LinearLayout肯定需要自定义,初始时,在第一个”推荐”的下面画上一个小圆点,然后通过viewpager的addOnPageChangeListener里的onPageScrolled方法,完成小圆点位置随页面滑动而变化。其实也挺简单的哈!接下来先上代码,然后讲一下原理。

 

首先自定义一个LinearLayout

MyLinearLayout:

package cn.zmit.myapplication;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.CornerPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.text.BoringLayout;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.LinearLayout;

/**
 * Created by kyle on 2016/3/14.
 */
public class MyLinearLayout extends LinearLayout {
    private int startX;//初始位置X坐标
    private Paint mPaint;
    private int moveX;//移动时不断变化的X坐标

    public MyLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        mPaint = new Paint();
        mPaint.setColor(Color.parseColor("#FFFFFF"));//画笔颜色
        mPaint.setStyle(Paint.Style.FILL);//画笔样式(填充内部)
    }

    public MyLinearLayout(Context context) {
        super(context, null);
    }

    /***
     * 开始画圆
     *
     * @param canvas
     */
    @Override
    protected void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);
        startX = getWidth() / 8;//最开始位置的X坐标
        canvas.save();//保存
        canvas.drawCircle(startX + moveX, getHeight() - 15, 5, mPaint);
        canvas.restore();//取出
    }

    /***
     * 当手指滑动时调用这个方法(在viewpager的onPageScrolled方法调用)
     *
     * @param position
     * @param Offset
     */
    public void changed(int position, float Offset) {
            moveX = (int) (getWidth() / 4 * Offset + position * getWidth() / 4);
            invalidate();//刷新
    }
}
既然用到ViewPager,当然需要fragment;

MyFragment.java:

package cn.zmit.myapplication;

import android.graphics.Color;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;


/**
 * Created by Administrator on 2016/3/14.
 */
public class MyFragment extends Fragment {
    public static final String TITLE = "title";

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        TextView textView = new TextView(getActivity());
        textView.setText(getArguments().getString(TITLE));
        textView.setTextColor(Color.parseColor("#000000"));
        textView.setGravity(Gravity.CENTER);
        return textView;
    }

    public static MyFragment getInstance(String title) {
        Bundle pBundle = new Bundle();
        pBundle.putString(TITLE, title);
        MyFragment fragment = new MyFragment();
        fragment.setArguments(pBundle);
        return fragment;
    }
}
MainActivity.java:

 

package cn.zmit.myapplication;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.Window;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class MainActivity extends FragmentActivity {
    private MyLinearLayout mLinearLayout;
    private ViewPager mViewpager;
    private FragmentStatePagerAdapter adapter;
    public List<String> lists = Arrays.asList("推荐", "排行", "分类","我的");
    private List<MyFragment> list = new ArrayList<>();

    private void assignViews() {
        mLinearLayout = (MyLinearLayout) findViewById(R.id.linearLayout);
        mViewpager = (ViewPager) findViewById(R.id.viewpager);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);
        assignViews();
        initData();
    }

    private void initData() {
        for (String title : lists) {
            MyFragment fragment = MyFragment.getInstance(title);
            list.add(fragment);
        }
        adapter = new FragmentStatePagerAdapter(getSupportFragmentManager()) {
            @Override
            public Fragment getItem(int position) {
                return list.get(position);
            }

            @Override
            public int getCount() {
                return list.size();
            }
        };
        mViewpager.setAdapter(adapter);
        mViewpager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                mLinearLayout.changed(position, positionOffset);
            }

            @Override
            public void onPageSelected(int position) {

            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
    }


}
好了,接下来开始讲一下原理。

这个例子最重要的地方,大家都能知道,在于自定义的LinearLayout,我们先从这里说起吧。

首先,

private int startX;//初始位置X坐标
private Paint mPaint;
private int moveX;//移动时不断变化的X坐标
startX为初始化原点的x坐标

maveX为当我们滑动ViewPager时动态改变的X数值。

然后,在构造方法中,初始画笔mPaint,设置颜色等属性。

接着,在dispatchDraw方法中执行画图功能,这个方法系统自动调用,主要是分发给子组件进行绘制。

代码解析:

startX = getWidth() / 8;//最开始位置的X坐标
初始化startX为屏幕的1/8,因为布局被分为4块,而原点又要位于每个模块的中间,所以初始的X应该为屏幕宽度的1/8。

canvas.save();//保存
canvas.drawCircle(startX + moveX, getHeight() - 15, 5, mPaint);
canvas.restore();//取出
sava和restore方法用于保存画布画图之前的状态和取出之前的状态,绘图时最好带上,这里不说了,有兴趣的同学可以去了解下。

drawCircle方法,顾名思义,画圆,第一个参数代表当前X坐标;第二个参数是高度,全程固定为布局的高度减去15,

大概在字和底部的中间。这个数值可以自己改,改到自己喜欢为止;第三个参数是半径,这里设为5,同理,可以根据喜好改;第四个参数是画笔,之前初始化完成了,这里直接加进去。

先看一下效果:

1

最后,重头戏来了,大家还记得在之前的ViewPager的addOnPageChangeListener里的onPageScrolled中做了什么吗?没错,在里面调用了一个方法:changed,让我们看一下,这个方法里做了什么

public void changed(int position, float Offset) {
        moveX = (int) (getWidth() / 4 * Offset + position * getWidth() / 4);
        invalidate();//刷新
}
看里面内容,将moveX的值变成了getWidth() / 4 * Offset + position * getWidth() / 4。

这到底是多少呢?先介绍一下两个参数,Offset,即滑动的宽度的百分比,比如我手指向左滑动,那么ViewPager的当前fragment也会随着手指往左边移动,当前fragment被隐藏的宽度占当前fragment的总宽度的百分比,即为Offset。Position就是当前fragment为第几个fragment,第一个的话,postion就为0,因为从0开始嘛!(注意,手指往左滑,position为当前position,手指往右滑,position为当前position-1)

介绍完参数后,开始说一下这个moveX到底变成了多少。

getWidth/4,屏幕宽度的1/4,即一个模块的宽度,乘以Offset,即随着手指滑动,使moveX的数值一直变大,直至正好为一个模块的宽,也就是从一个模块,滑到了另一个模块。听着已经可以了,但是不要忘记,Offset每次滑动后,都会变成0,也就是说,假设就这样完事的话,你只能将小圆点从第一个模块移动到第二个模块,无论你怎么滑。

好了,接着,后面还加了position * getWidth() / 4,即当前fragment的position乘以当前模块的宽,这样就解决了只能滑到第二个模块的问题,因为假设当前fragment为第二个,position为1,原点位于模块2,即“排行”,X的数值为X=startX+moveX;

startX=getWidth() / 8 ;

moveX=getWidth() / 4 * Offset + 1* getWidth() / 4;

当我们没动时,X的数值等于”排行”两字中间的X值,

X=getWidth() / 8+1* getWidth() / 4;

当我们往左滑动,Offset不断变大,直至1,position为1

X=getWidth() / 8+getWidth() / 4 +1* getWidth() / 4;

正好比没滑动时大一个模块,即滑到了第三个模块”分类”

当我们往右滑动,Offset不断变大,直至1,position为0

X=getWidth() / 8+getWidth() / 4 +0* getWidth() / 4;

正好比没滑动时小一个模块,即滑到了第一个模块”推荐”

效果图由于条件限制,没法录制gif,所以大家可以自己把代码运行一下看效果。

总结:这个例子主要是运用了viewGroup的画图功能,自定义了一个带圆点的LinearLayout,随后运用ViewPager的滑动参数,动态改变圆点位置。主要在于了解viewPager的运行机制,还有需要了解画笔的使用。

原文来自 :http://blog.it985.com/15824.html

ListView在开发中用到的非常的多,但是许多的朋友对于ListView这一块不满意了,下面我们来看一篇关于Android开发之ListView优化方案?>ViewHolder教程。

我们使用ViewHolder时,把每一个item的子View控件对象都放在ViewHolder中,当第一次创建convertView对象时,便把这些item的子View控件对象findViewById实例化出来并保存到ViewHolder的对象中。然后用convertView的setTag将viewHolder对象设置到Tag中, 当以后加载ListView的item时便可以直接从Tag中取出复用ViewHolder对象中的,不需要再findViewById找item的子控件对象了。这样便大大提高了性能。

但是,某些情况下,这种优化技术便出现了一种问题,举个例子,当我们由于项目需要,需要在ListView中用到CheckBox时,那么,就会出现这样的情况:

假设一个ListView有10个Item,当我选择第一个Item的CheckBox之后,往下滑动到原先不可见的位置时就会发现,还有其他的CheckBox也被选中了,这样就造成了很不好的用户体验。

先上出现了这种问题的代码:

布局文件:

activity_listview.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
<ListView
    android:id="@+id/listview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"></ListView>
</LinearLayout>
item_list.xml   一个CheckBox和一个TextView,设为100dp高的原因是,必须有未显示的Item,ListView才会去复用View,如果一个屏幕显示了全部的Item,那么就不回复用了。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="100dp">
    <CheckBox
        android:layout_centerVertical="true"
        android:layout_marginLeft="10dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/textView"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</RelativeLayout>
</LinearLayout>
MyAdapter.java

package cn.zmit.myapplication;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import java.util.List;


/**
 * Created by Administrator on 2016/3/23.
 */
public class MyAdapter extends BaseAdapter {
    private List<String> list;
    private Context context;

    public MyAdapter(List<String> lists, Context contexts) {

        list = lists;
        context = contexts;
    }

    @Override
    public int getCount() {
        return list.size();
    }

    @Override
    public Object getItem(int position) {
        return list.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }


    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if (convertView == null) {
            holder = new ViewHolder();
            convertView = View.inflate(context, R.layout.item_list, null);
            holder.textView = (TextView) convertView.findViewById(R.id.textView);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        holder.textView.setText(list.get(position));

        return convertView;
    }

    private class ViewHolder {
        TextView textView;
    }
}
ListVeiwDemo.java

package cn.zmit.myapplication;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Administrator on 2016/3/18.
 */
public class ListViewDemo extends Activity {
    private ListView listView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_listview);
        listView= (ListView) findViewById(R.id.listview);
        List<String> list=new ArrayList<>();
        for(int i=0;i<10;i++){
            list.add(i+"");
        }
        MyAdapter adapter=new MyAdapter(list,this);
        listView.setAdapter(adapter);
    }

}
 

非常正常的一个ListView实现过程,贴代码的原因是担心有初学者不懂我在说什么。大家可以把代码拷贝一下或者自己编写看一下效果。

 

接下来说一下怎么解决!!!!
首先,定义一个Map,

Map<Integer,View>map=new HashMap<>();
当convertView为null时,在convertView和子控件加载完成后,将convertView加入map:

map.put(position,convertView);
我们想一想,这时候,在前面判断的时候,还应该是

if (convertView == null)
这样吗?当然不是,换成这样:

if (map.get(position)==null)
也就是说,只要你这个Item没被加载过,就给我重新加载!

然后在下面的else里这样写:

else {
    convertView=map.get(position);
    holder = (ViewHolder) convertView.getTag();
}
假设map里有这个View,就拿出来用。

全部解决完问题的Adapter的getView部分代码为:
Map<Integer,View>map=new HashMap<>();
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    ViewHolder holder;
    if (map.get(position)==null) {
        holder = new ViewHolder();
        convertView = View.inflate(context, R.layout.item_list, null);
        holder.textView = (TextView) convertView.findViewById(R.id.textView);
        map.put(position,convertView);
        convertView.setTag(holder);
    } else {
        convertView=map.get(position);
        holder = (ViewHolder) convertView.getTag();
    }
    holder.textView.setText(list.get(position));

    return convertView;
}

[!--infotagslink--]

相关文章

  • PHP session_start()很慢问题分析与解决办法

    本文章来给各位同学介绍一下关于PHP session_start()很慢问题分析与解决办法,希望碰到此问题的同学可进入参考。 最近在做东西的时候发现一个问题 有一个接口挂...2016-11-25
  • php生成二维码中文乱码问题解决方法

    最近做了个扫描二维码得到vcard的项目,遇到一个问题,有一部分生成完的二维码,用android系统手机扫描后得到的vcard中的中文姓名是乱码,经过比对发现,这部分vcard中ORG这个...2016-11-25
  • php中json_decode()和json_encode()用法与中文不显示解决办法

    本文章介绍了关于php中json_decode()和json_encode()用法与中文不显示解决办法,有需要的朋友可以参考一下下。 php中json_decode()和json_encode() 1.json_decode(...2016-11-25
  • phpexcel导出数据身份证后四位0000解决办法

    在php中我们如果要导入excel数据我们通常会使用phpexcel插件了,但是有朋友会发与使用phpexcel导出数据出现身份证后四位是0000情况了,下面我们就来看解决办法。 最...2016-11-25
  • 401错误码代表什么 401错误解决办法

    401是HTTP状态码的一种,属于“请示错误”,表示请求可能出错,已妨碍了服务器对请求的处理。具体的401错误是指:未授权,请求要求进行身份验证。登录后,服务器可能会返回对页面...2017-01-22
  • apache网站提示503错误解决办法

    Apache status 503 的原因大致有如下几种情况 : 1、 CPU 负载过高,服务器响应不过来,返回503 2、 系统连接数超限,超过MaxVhostClients的上限,返回503 3、 单IP连接数超限,超过M...2016-01-28
  • Perl CPAN::Modulelist的解决办法

    今天用CPAN安装Term::ReadLine,报了个这样的错误 Going to read /root/.cpan/sources/modules/03modlist.data.gz Can't locate object method "data" via package "C...2016-11-25
  • 运行vbs脚本报错无效字符、中文乱码的解决方法(编码问题)

    今天在写一个vbs的时候,发现中文乱码,后来写好代码正常运行的代码压缩一下给了同事,发现报无效字符,经过验证后发现原来是编码的问题导致,这里就为大家分享一下...2020-06-30
  • phpStudy访问速度慢和启动失败的解决办法

    下面给大家介绍phpstudy访问速度慢的解决办法。1、修改mysql数据库链接地址为ip地址127.0.0.1。2、使用最新版本,这个坑了我好久时间。下面一段内容是关于phpstudy启动失败的解决办法。php5.3、5.4和apache都是用vc9编...2015-11-24
  • PHP Curl出现403错误的解决办法

    自己用的小PHP应用,使用curl抓网页下来处理,为了穿墙方便,使用Privoxy作为代理,便于选择哪些网站使用proxy、哪些不用。但今天却遇到了奇怪的问题,访问google baidu这些网站居然都返回403错误,而访问其他的一些网站没事,如果...2014-05-31
  • 关于Mysql中文乱码问题该如何解决(乱码问题完美解决方案)

    最近两天做项目总是被乱码问题困扰着,这不刚把mysql中文乱码问题解决了,下面小编把我的解决方案分享给大家,供大家参考,也方便以后自己查阅。首先:用show variables like “%colla%”;show varables like “%char%”;这两条...2015-11-24
  • PHP判断上传文件类型的解决办法

    分享给大家php判断上传文件类型的方法,大家一起学习学习。/** * 读取文件前几个字节 判断文件类型 * @return String */ function checkTitle($filename){ $file=fopen($filename, "rb"); $bin=fread($file, 2); /...2015-10-21
  • PHP json_encode() 函数详解及中文乱码问题

    在 php 中使用 json_encode() 内置函数(php > 5.2)可以使用得 php 中数据可以与其它语言很好的传递并且使用它。这个函数的功能是将数值转换成json数据存储格式。<&#63;php$arr = array ( 'Name'=>'希亚', 'Age'...2015-11-08
  • android.os.BinderProxy cannot be cast to com解决办法

    本文章来给大家介绍关于android.os.BinderProxy cannot be cast to com解决办法,希望此文章对各位有帮助呀。 Android在绑定服务的时候出现java.lang.ClassCastExc...2016-09-20
  • MYSQL数据库使用UTF-8中文编码乱码的解决办法

    1.用phpmyadmin创建数据库和数据表 创建数据库的时候,请将“整理”设置为:“utf8_general_ci” 或执行语句: 复制代码 代码如下:CREATE DATABASE `dbname` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; 创...2015-10-21
  • php的mail函数发送UTF-8编码中文邮件时标题乱码的解决办法

    最近遇到一个问题,就是在使用php的mail函数发送utf-8编码的中文邮件时标题出现乱码现象,而邮件正文却是正确的。最初以为是页面编码的问题,发现页面编码utf-8没有问题啊,找了半天原因,最后找到了问题所在。 1.使用 PEAR 的...2015-10-21
  • PHP页面转UTF-8中文编码乱码的解决办法

    对于乱码这个问题php开发者几乎都会有碰到过,我们下面主要是介绍了php文件乱码和页面乱码。PHP页面转UTF-8编码问题 1.在代码开始出加入一行: header("Content-Type: text/html;charset=utf-8"); 2.PHP文件编码问题...2015-10-21
  • 解决HttpPost+json请求---服务器中文乱码及其他问题

    这篇文章主要介绍了解决HttpPost+json请求---服务器中文乱码及其他问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-22
  • Android开发之PhoneGap打包及错误解决办法

    下面来给各位简单的介绍一下关于Android开发之PhoneGap打包及错误解决办法,希望碰到此类问题的同学可进入参考一下哦。 在我安装、配置好PhoneGap项目的所有依赖...2016-09-20
  • Ubuntu15下mysql5.6.25不支持中文的解决办法

    apt-get install 安装的,不是源码包安装的mysql1 修改mysql的配置文件/etc/mysql/conf.d/mysql.cnf在[mysql]的下方加入如下语句:(注:这个文件下没有配置,只有【mysql】)no-auto-rehash default-character-set=utf8/etc/...2015-10-21