Android 线程的初步了解

一、操作系统中线程和进程的概念

现在的操作系统是多任务操作系统。多线程是实现多任务的一种方式。
进程是指一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间,一个进程中可以启动多个线程。比如在Windows系统中,一个运行的exe就是一个进程。
线程是指进程中的一个执行流程,一个进程中可以运行多个线程。比如java.exe进程中可以运行很多线程。线程总是属于某个进程,进程中的多个线程共享进程的内存。

二、为什么要使用多线程

举个例子就如同节假日的公路,如果只有一条通行道的好就会出现塞车的情况,然后就会使整条道路堵塞不能通行。如果有多条马路的话,即使有一条马路堵塞很拥挤我可以先择其他马路去走,那么我通行的时间就没有受到影响。
线程的作用就是如此,我们可以把需要耗时的操作放到子线程里面去,等子线程完成任务时再在主线程做出相应的响应。

三、线程的状态与生命周期

Java语言使用Thread类及其子类的对象来表示线程,新建的线程在它的一个完整生命周期中通常要经历一下四种状态。

  1. 新建
  2. 运行
  3. 中断
  4. 死亡

在Java中有4中出现中断的原因:1. JVM将CPU资源从当前线程切换给其他线程。2. 线程使用CPU资源间使用了sleep。3. 线程使用CPU期间执行wait。 4. 线程使用CPU资源期间,执行某个操作进入阻塞。

四、常见更新UI的方式

在本例中我只使用了两种方式实现UI的更新即:handler+Thread和用runOnUiThread方法。
从实现原理上,两者别无二致,runOnUiThread也是借助Handler实现的。
对于使用场景,runOnUiThread用法简单,并且共享了同一个Handler,用起来高效、方便。另外,如果在主线程中直接调用,runOnUiThread也可以判断并立即执行,不再推入消息队列。而Handler由于更加基础,所以可定制性要比runOnUiThread强,可以实现标记、延时等功能,并且可以推入其他消息循环线程而非主线程。
使用runOnUiThread方法

public class TabletimeActivity2 extends AppCompatActivity {

    private String mSemester;

    private String mClassName;

    private String strJson;

    private GridView mGridView;

    private final String url ="http://192.168.3.151:8080/Educational/GetJson";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_tabletime2);
        getLogin();
        Request();
    }

    public void getLogin(){
        mGridView= (GridView) findViewById(R.id.gridview);
        Intent Intent=getIntent();
        mSemester=Intent.getStringExtra("Semester");
        mClassName=Intent.getStringExtra("ClassName");
        ClassBean Cbean=new ClassBean();
        Cbean.setClassName(mClassName);
        Cbean.setSemester(mSemester);
        Gson gson = new Gson();
         strJson = gson.toJson(Cbean);
    }
    public void Request(){

        new Thread(new Runnable() {
            @Override
            public void run() {
                OkHttpClient client = new OkHttpClient();
                MediaType JSON = MediaType.parse("application/json; charset=utf-8");
                //把请求的内容字符串转换 为json
                RequestBody body = RequestBody.create(JSON, strJson);
                Log.i("Json",strJson);
                Request request = new Request.Builder()
                        .url(url)
                        .post(body)
                        .build();
                Response response = null;
                try {
                    response = client.newCall(request).execute();
                    String result = response.body().string();
                    if (result!=null){
                        Gson gson=new Gson();
                        List<Table> tables = gson.fromJson(result, new
                                TypeToken<List<Table>>()
                                {}.getType());
                        InitGridView(tables);

                    }

                } catch (IOException e) {
                    e.printStackTrace();
                    Log.i("错误:",  e.toString());
                }
            }
        }).start();
    }
    private void InitGridView(final List<Table> tables) {
            runOnUiThread(new Runnable() {
            @Override
            public void run() {
                List<String> strList = new ArrayList<String>();
                for (Table table : tables) {
                    strList.add(table.getSection());
                    strList.add(table.getOne());
                    strList.add(table.getTwo());
                    strList.add(table.getThree());
                    strList.add(table.getFour());
                    strList.add(table.getFive());
                    strList.add(table.getSix());
                    strList.add(table.getSeven());
                }
               MyAdapter adapter = new MyAdapter(TabletimeActivity2.this, strList);
                mGridView.setAdapter(adapter);
            }
        });
    }
}

向服务器发送申请并返回数据属于一个耗时操作,我们应该把它放在一个子线程中,开启一个Thread发送申请并得到数据后,利用runOnUiThread(Runnable)把更新ui的代码创建在Runnable中,然后在需要更新ui时,就能在ui程序中被调用。如果当前线程是UI线程,那么行动是立即执行。如果当前线程不是UI线程,操作是发布到事件队列的UI线程。
handler+Thread

public  class RequestOrResponse {
    private final String url ="http://192.168.3.151:8080/Educational/GetJson";

    private  String StrJson;

    public void Request(final String Strjson) throws IOException {

        new Thread(new Runnable() {
            @Override
            public void run() {
                OkHttpClient client = new OkHttpClient();
                MediaType JSON = MediaType.parse("application/json; charset=utf-8");
                //把请求的内容字符串转换 为json
                RequestBody body = RequestBody.create(JSON, Strjson);
                Log.i("Json",Strjson);
                Request request = new Request.Builder()
                        .url(url)
                        .post(body)
                        .build();
                Response response = null;
                try {
                    response = client.newCall(request).execute();
                    String result = response.body().string();
                    if (result!=null){

                        Message message=new Message();
                        message.what=1;
                        message.getData().putString("result",result);
                        handler.sendMessage(message);

                    }

                } catch (IOException e) {
                    e.printStackTrace();
                    Log.i("错误:",  e.toString());

                }

            }
        }).start();
    }

    private Handler handler=new Handler(){
        @Override
        public void handleMessage(Message msg) {

            if (msg.what==1){
                StrJson=msg.getData().getString("result");
                Log.i("result",StrJson);
            }
        }

    };
    public String getStrJson(){
        return StrJson;
    }
}

在申请请求得到响应时,创建一个Message发送到handler,然后在UI线程中创建一个handler,取到子线程的Message。然后就可以在其他Activity中调用该类的方法得到返回的数据。

-个人总结-

我对线程的了解还是太少,因为刚接触总是觉得它难然后就很少用它。在调试时经常出现线程堵塞的情况,还不懂怎么入手解决。想得到子线程的值还可以用回调函数这个方法来实现,线程的实现原理只是了解皮毛。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,569评论 25 707
  • 今天leo主要总结线程方面的,分为以下几个知识点: • 认识线程 • 线程的基本用法 • 线程同步 • 子线程...
    SingleoD阅读 9,161评论 25 77
  • java 接口的意义-百度 规范、扩展、回调 抽象类的意义-乐视 为其子类提供一个公共的类型封装子类中得重复内容定...
    交流电1582阅读 2,147评论 0 11
  • 李嘉诚说所有的失败都是自我管理的失败,德鲁克的这篇文章则告诉我们如何做到自我管理,他认为任何一个人都可以通过学习掌...
    kiwi_baba阅读 183评论 0 0
  • 如果成长就是跟恶人相处,那么我们便进入了误区,而这个所谓的成长,让我们变成了一个个的刺猬,别人不敢欺负,也不敢接触...
    惜昔言阅读 186评论 0 1