Android AsynTask更新主界面

虽然今天礼拜六还在加班,但是在等接口,所以还是有很多时间来自己学点东西的,所以就接着昨天的来。今天继续学的是不通过主线程来更新主线程的界面的问题。

  昨天是用的开启线程调用Handler来更新线程,那个效果用的方面比较广阔,那么我们还有几种方法将耗时的代码剥离出来不在主线程里面执行,然后通过各种方法来更新UIThread .今天学到的是利用AsynTask来更新主界面的空间。

  然后我们先来说说AsynTask:

  AsynTask:Asynchronous Task(异步任务)

使用过AsyncTask 的同学都知道一个异步加载数据最少要重写以下这两个方法:

  • doInBackground(Params…) 后台执行,比较耗时的操作都可以放在这里。注意这里不能直接操作UI。此方法在后台线程执行,完成任务的主要工作,通常需要较长的时间。在执行过程中可以调用publicProgress(Progress…)来更新任务的进度。
  • onPostExecute(Result)  相当于Handler 处理UI的方式,在这里面可以使用在doInBackground 得到的结果处理操作UI。 此方法在主线程执行,任务执行的结果作为此方法的参数返回

有必要的话你还得重写以下这三个方法,但不是必须的:

  • onProgressUpdate(Progress…)   可以使用进度条增加用户体验度。 此方法在主线程执行,用于显示任务执行的进度。
  • onPreExecute()        这里是最终用户调用Excute时的接口,当任务执行之前开始调用此方法,可以在这里显示进度对话框。
  • onCancelled()             用户调用取消时,要做的操作

使用AsyncTask类,以下是几条必须遵守的准则:

  • Task的实例必须在UI thread中创建;
  • execute方法必须在UI thread中调用;
  • 不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)这几个方法;
  • 该task只能被执行一次,否则多次调用时将会出现异常;

  好了继续以往风格,再说需求:

    需求是在界面通过输入一个完整的网址然后通过点击按钮来访问网络,在访问的时候展示一个进度条,然后将得到的网页代码显示在主界面上。

  

然后上代码:TestAsynTaskActivity

package com.example.testandroid;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View.OnClickListener;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.ArrayList;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class TestAsynTaskActivity extends Activity implements OnClickListener {

    private TextView message;
    private Button open;
    private EditText url;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test_asyn_task);
        message = (TextView) findViewById(R.id.show);
        url = (EditText) findViewById(R.id.url);
        open = (Button) findViewById(R.id.open);
        open.setOnClickListener(this);
    }

    private void connect() {
        PageTask task = new PageTask(this);
        task.execute(url.getText().toString());
    }

    class PageTask extends AsyncTask<String, Integer, String> {
        // 可变长的输入参数,与AsyncTask.exucute()对应
        ProgressDialog pdialog;

        public PageTask(Context context) {
            pdialog = new ProgressDialog(context, 0);
            pdialog.setButton("cancel", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int i) {
                    dialog.cancel();//这个方法过时了。
                }
            });
            pdialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
                public void onCancel(DialogInterface dialog) {
                    finish();
                }
            });
            pdialog.setCancelable(true);
            pdialog.setMax(100);
            pdialog.setTitle("正在请求网络!");
            pdialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
            pdialog.show();

        }

        @Override
        protected String doInBackground(String... params) {

            try {

                HttpClient client = new DefaultHttpClient();
                // params[0]代表连接的url
                HttpGet get = new HttpGet(params[0]);
                HttpResponse response = client.execute(get);
                HttpEntity entity = response.getEntity();
                long length = entity.getContentLength();
                InputStream is = entity.getContent();
                String s = null;
                if (is != null) {
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();

                    byte[] buf = new byte[128];

                    int ch = -1;

                    int count = 0;

                    while ((ch = is.read(buf)) != -1) {

                        baos.write(buf, 0, ch);

                        count += ch;

                        if (length > 0) {
                            // 如果知道响应的长度,调用publishProgress()更新进度
                            publishProgress((int) ((count / (float) length) * 100));
                        }

                        // 让线程休眠100ms
                        Thread.sleep(100);
                    }
                    s = new String(baos.toByteArray());
                }
                // 返回结果
                return s;
            } catch (Exception e) {
                e.printStackTrace();

            }

            return null;

        }

        @Override
        protected void onCancelled() {
            super.onCancelled();
        }

        @Override
        protected void onPostExecute(String result) {
            // 返回HTML页面的内容
            message.setText(result);
            pdialog.dismiss();
        }

        @Override
        protected void onPreExecute() {
            // 任务启动,可以在这里显示一个对话框,这里简单处理
            message.setText("正在更新。。。");
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            // 更新进度
            System.out.println("" + values[0]);
            message.setText("" + values[0]);
            pdialog.setProgress(values[0]);
        }

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.open:
            connect();
            break;
        default:
            break;
        }
    }

}

下面是xml文件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent" >

            <TextView
                android:id="@+id/show"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="15dp"
                android:background="@drawable/shape1"
                android:hint="@string/tv_hint" />

            <EditText
                android:id="@+id/url"
                android:layout_width="200dp"
                android:layout_height="wrap_content"
                android:layout_below="@id/show"
                android:layout_marginLeft="15dp"
                android:layout_marginTop="15dp"
                android:background="@null"
                android:hint="在这里输入网址" />

            <Button
                android:id="@+id/open"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@id/url"
                android:layout_marginLeft="15dp"
                android:layout_marginTop="15dp"
                android:background="@drawable/shape2"
                android:text="打开网页"
                android:textColor="#FFFFFF"
                android:textSize="20dp" />
        </RelativeLayout>
    </ScrollView>

</RelativeLayout>

最后,因为是要访问网络,我们要记得在manifest文件里面加入INTERNET权限。好啦简单的一个AsynTask的实现就完成了!

时间: 2024-10-22 07:05:57

Android AsynTask更新主界面的相关文章

Android应用经典主界面框架之一:仿QQ (使用Fragment, 附源码)

最近反复研究日常经典必用的几个android app,从主界面带来的交互方式入手进行分析,我将其大致分为三类.今天记录第一种方式,即主界面下面有几个tab页,最上端是标题栏,tab页和tab页之间不是通过滑动切换的,而是通过点击切换tab页.早期这种架构一直是使用tabhost+activitygroup来使用,随着fragment的出现及google官方也大力推荐使用fragment,后者大有代替前者之势.本文也使用fragment进行搭建,标题中的"经典"指这种交互经典,非本文的代

android异步更新UI界面的方法

在android平台下,进行多线程编程时,经常需要在主线程之外的一个单独的线程中进行某些处理,然后更新用户界面显示.但是,在主线线程之外的线程中直接更新页面显示的问题是:系统会报这个异常,android.view.viewroot$calledfromwrongthreadexception: only the original thread that created a view hierarchy can touch its views. (只有原始创建这个视图层次(view hierach

Android应用经典主界面框架之二:仿网易新闻客户端、CSDN 客户端 (Fragment ViewPager)

第二种主界面风格则是以网易新闻.凤凰新闻以及新推出的新浪博客(阅读版)为代表,使用ViewPager+Fragment,即ViewPager里适配器里放的不是一般的View,而是Fragment.所以适配器不能继承PagerAdapter,而要继承FragmentPagerAdapter,这是在android.support.v4.app.FragmentPagerAdapter包里的.有点奇葩的是,FragmentPagerAdapter只在这个包里有,在android.app.*这个包下面么

ScrollView + viewpager实现android的app主界面效果

ScrollView + viewpager实现android的app主界面效果 Android的主界面一般由两部分组成:导航栏,滑动的分屏(我自己这么叫的).其中滑动的分屏肯定是用的fragment,具体的承载的控件是viewpager.而导航分页栏用的控件就有很多了,tabhost,Scrollview或者自定义的都行. 个人认为tabhost和Scrollview都是比较好的,因为后期的可拓展性比较好,除非导航栏界面确实属于"自定义"范畴,基本上我们可以选择这两样就可以了. 其实

Android子线程更新主界面

学习什么的还是要真正的有应用,有需求才能在最短的时间里面牢牢掌握一项技术. 今天就是这样的,产品一个需求下来,十万火急啊.然后之前只稍稍接触过,只能硬着头皮上了.最后牢牢地掌握了最简单的Handler技术,闲话不多说了! 每一个做android的人都知道,android的内存可谓是存M存金啊!然后我们自然知道,而且Google在设计的时候也充分的考虑到了这一点,所以,我们的UIThread里面一般不做耗时的工作,比如请求网络,比如执行一些比较耗时的逻辑,比如比如加载图片,比如,哦,暂时只碰到过这

Android应用经典主界面框架之一:仿QQ (使用Fragment)

最近反复研究日常经典必用的几个android app,从主界面带来的交互方式入手进行分析,我将其大致分为三类.今天记录第一种方式,即主界面下面有几个tab页,最上端是标题栏,tab页和tab页之间不是通过滑动切换的,而是通过点击切换tab页.早期这种架构一直是使用tabhost+activitygroup来使用,随着fragment的出现及google官方也大力推荐使用fragment,后者大有代替前者之势.本文也使用fragment进行搭建,标题中的“经典”指这种交互经典,非本文的代码框架结构

Android代码优化,主界面卡住

============问题描述============ 程序打开进入MainActivity,其实MainActivity没做什么操作,MainActivity是加载sildingmenu+actionbar+fragment,具体业务操作是在fragment里面进行的,但是程序会在MainActivity那里显示MainActivity的xml,其实什么都没有,但是会停留1~5秒左右,才去显示fragment的xml,感觉很奇怪,如果卡也是会卡在fragment那里,结果fragment又不

Android应用经典主界面框架之二:仿网易新闻client、CSDN client (Fragment ViewPager)

另外一种主界面风格则是以网易新闻.凤凰新闻以及新推出的新浪博客(阅读版)为代表.使用ViewPager+Fragment,即ViewPager里适配器里放的不是一般的View.而是Fragment.所以适配器不能继承PagerAdapter,而要继承FragmentPagerAdapter,这是在android.support.v4.app.FragmentPagerAdapter包里的.有点奇葩的是,FragmentPagerAdapter仅仅在这个包里有,在android.app.*这个包以

Android Tab类型主界面 Fragment+TabPageIndicator+ViewPager

文章地址: Android项目Tab类型主界面大总结 Fragment+TabPageIndicator+ViewPager 1.使用ViewPager + PagerAdapter 每个页面的内容都在一个Activity中,维护起来会比较麻烦 2.FragmentManager + Fragment 每个页面的内容分开,但是只能点击按钮换页 3.ViewPager + FragmentPagerAdapter 综合前两种方式,比较好 4.TabPageIndicator + ViewPager