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 tables = gson.fromJson(result, new
                                TypeToken>()
                                {}.getType());
                        InitGridView(tables);

                    }

                } catch (IOException e) {
                    e.printStackTrace();
                    Log.i("错误:",  e.toString());
                }
            }
        }).start();
    }
    private void InitGridView(final List
tables) { runOnUiThread(new Runnable() { @Override public void run() { List strList = new ArrayList(); 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中调用该类的方法得到返回的数据。

-个人总结-

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

你可能感兴趣的:(Android 线程的初步了解)