Android AsyncTack 异步任务实例详解


Posted in PHP onNovember 02, 2016

Android AsyncTack 异步任务

              这里写一个小实例,来学习巩固Android AsyncTack 异步任务的知识,以便在项目中使用。

介绍一下如何使用

1, 继承AsyncTask

public class MyTask extends AsyncTask<Params, Progrss, Result>

我们来说一下这三个泛型的作用:

Params: 调用异步任务时传入的类型 ;

Progress : 字面意思上说是进度条, 实际上就是动态的由子线程向主线程publish数据的类型

Result : 返回结果的类型

2, 重写这个类的抽象方法doInBackground, 当然它也有几个方法需要重写, 我们一一看来

doInBackground(抽象方法, 必须实现)

/* 唯一执行在子线程中的方法
 *  所以不可以进行UI的更新
 * @param params
 * @return
 */
@Override//返回值: Result    参数: Param
protected String doInBackground(TextView... params) {
  text = params[0];
  Random random = new Random();
  for (int i = 0; i < 50; i++) {
    //要进行进度的更新
    publishProgress(i);
    //不能直接调用onProgressUpdate方法,
    //这样会使得onProgressUpdate在子线程中运行
    try {
      Thread.sleep(random.nextInt(10) * 10);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }
  return "已完成";
}

下面三个方法根据具体情况选择使用

//执行doInBackground之前调用
  @Override
  protected void onPreExecute() {
    super.onPreExecute();
  }
@Override//与publishProgress(i)对应
  protected void onProgressUpdate(Integer... values) {
    super.onProgressUpdate(values);
    text.setText(String.valueOf(values[0]));
  }
//在doInBackground之后执行
  @Override // 参数s为 Result
  protected void onPostExecute(String s) {
    super.onPostExecute(s);
    text.setText(s);
  }

3, 执行异步任务

有两种方式, 我已经把区别写在了注释中
/*
 直接execute异步任务, 都是同一线程去执行
*/

text = (TextView) findViewById(R.id.main_text1);
new MyTask().execute(text);
text = (TextView) findViewById(R.id.main_text2);
new MyTask().execute(text);
text = (TextView) findViewById(R.id.main_text3);
new MyTask().execute(text);
text = (TextView) findViewById(R.id.main_text4);
new MyTask().execute(text);
/*
  启动多条线程来执行异步任务
  API11以上可以使用
*/
 ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(4);
 text = (TextView) findViewById(R.id.main_text1);
 new MyTask().executeOnExecutor(executor, text);
 text = (TextView) findViewById(R.id.main_text2);
 new MyTask().executeOnExecutor(executor, text);
 text = (TextView) findViewById(R.id.main_text3);
 new MyTask().executeOnExecutor(executor, text);
 text = (TextView) findViewById(R.id.main_text4);
 new MyTask().executeOnExecutor(executor, text);

注意: 如果我们直接去execute我们的任务, 它(任务) 只会在同一个子线程中运行, 所以上述第一种方式启动时, 四个任务顺次执行(就是一个任务执行完了再执行另一个); 而第二种方式, 给它创建了线程池, 这样会自动给它创建新的子线程, 所有的任务不是顺序执行, 而是几个线程”同时执行”

获取网络数据呈现在Webview和下载图片和其共存的案例

1, 首先我们要来一个布局, 具体需求是这样的, 在WebView之上有个ImageView, 并且, ImageView可以随WebView滚动, 所以这个时候我们想到了用ScrollView, 但是大家一定不要忘记, ScrollView只能包含一个控件, 所以我们可以用LinearLayout包裹一下即可

<ScrollView
  android:layout_width="match_parent"
  android:layout_height="match_parent">
  <LinearLayout
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ImageView
      android:id="@+id/main2_image"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content" />
    <WebView
      android:id="@+id/main2_web"
      android:layout_width="match_parent"
      android:layout_height="match_parent"/>
  </LinearLayout>
</ScrollView>

2, 接下来我们要有一个实体类, 用来存放从网页上下载的内容(这里加注解原因在于我们要使用GSON解析来自网页的内容)

public class Entry {
  @SerializedName("title")
  private String title;
  @SerializedName("message")
  private String message;
  @SerializedName("img")
  private String image;

  public String getTitle() {
    return title;
  }
  ...//省略其余getter和setter方法
  public void setImage(String image) {
    this.image = image;
  }
}

3, 那我们接下解决的问题就是 如何下载图片? 如何下载web内容? , 那我们写两个通用的工具类

下载工具类(通用型)

/**
 * Created by Lulu on 2016/8/31.
 * <p/>
 * 通用下载工具类
 */
public class NetWorkTask<T> extends AsyncTask<NetWorkTask.Callback<T>, Void, Object> {

  private NetWorkTask.Callback<T> callback;
  private Class<T> t;
  private String url;

  public NetWorkTask(String url, Class<T> t) {
    this.url = url;
    this.t = t;
  }
  @Override
  protected Object doInBackground(Callback<T>... params) {
    callback = params[0];

    try {

      HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
      connection.setRequestMethod("GET");
      connection.setDoInput(true);
      int code = connection.getResponseCode();
      if (code == 200) {
        InputStream is = connection.getInputStream();
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        byte[] buffer = new byte[102400];
        int length;
        while ((length = is.read(buffer)) != -1) {
          bos.write(buffer, 0, length);
        }
        return bos.toString("UTF-8");
      } else {
        return new RuntimeException("服务器异常");
      }

    } catch (Exception e) {
      e.printStackTrace();
      return e;
    }

  }

  @Override
  protected void onPostExecute(Object o) {
    super.onPostExecute(o);
    if(o instanceof String) {
      String str = (String) o;
      Gson gson = new Gson();
      T t = gson.fromJson(str, this.t);
      callback.onSuccess(t);
    }
    if( o instanceof Exception) {
      Exception e = (Exception) o;
      callback.onFailed(e);
    }
  }
  public interface Callback<S> {
    void onSuccess(S t);
    void onFailed(Exception e);
  }
}

图片加载器(通用型)

/**
 * Created by Lulu on 2016/8/31.
 * 图片网络加载器
 * 下载成功返回Bitmap
 * 否则返回null
 */
public class ImageLoader extends AsyncTask<String, Void, Bitmap>{

  private ImageView image;

  public ImageLoader(ImageView image) {
    this.image = image;
    image.setImageResource(R.mipmap.ic_launcher);
  }

  @Override
  protected void onPreExecute() {
    super.onPreExecute();

  }

  @Override
  protected Bitmap doInBackground(String... params) {
    String url = params[0];
    try {
      HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
      connection.setRequestMethod("GET");
      connection.setDoInput(true);
      int code = connection.getResponseCode();
      if (code == 200) {
        InputStream is = connection.getInputStream();
        return BitmapFactory.decodeStream(is);
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
    return null;
  }


  @Override
  protected void onPostExecute(Bitmap bitmap) {
    super.onPostExecute(bitmap);
    if (bitmap != null) {
      image.setImageBitmap(bitmap);
    } else {
      image.setImageResource(R.mipmap.failed);
    }
  }
}

4, 测试Activity

注意: 看如何解决大图在webView中不左右滑动的问题!

public class Main2Activity extends AppCompatActivity implements NetWorkTask.Callback<Entry>{
  private WebView web;
  private ImageView image;
  //解决大图在webView中不左右滑动的问题
  private static final String CSS = "<style>img{max-width:100%} </style>";
  private String title;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main2);
    web = (WebView) findViewById(R.id.main2_web);
    image = (ImageView) findViewById(R.id.main2_image);
    new NetWorkTask<>("http://www.tngou.net/api/top/show?id=13122", Entry.class).execute(this);
  }
  @Override
  public void onSuccess(Entry t) {
    web.loadDataWithBaseURL("", t.getMessage(), "text/html; charset=utf-8", "UTF-8", null);
    new ImageLoader(image).execute("http://img.blog.csdn.net/20160829134937003");
  }
  @Override
  public void onFailed(Exception e) {
    web.loadDataWithBaseURL("", "加载失败", "text/html; charset=utf-8", "UTF-8", null);
  }
}

5.效果图:

Android AsyncTack 异步任务实例详解

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

PHP 相关文章推荐
mysql 全文搜索 技巧
Apr 27 PHP
php !function_exists(&quot;T7FC56270E7A70FA81A5935B72EACBE29&quot;))代码解密
Jan 07 PHP
使ecshop模板中可引用常量的实现方法
Jun 02 PHP
php数组函数序列之array_search()- 按元素值返回键名
Nov 04 PHP
php $_SERVER windows系统与linux系统下的区别说明
Feb 14 PHP
编写PHP脚本使WordPress的主题支持Widget侧边栏
Dec 14 PHP
php微信开发之批量生成带参数的二维码
Jun 26 PHP
PHP版微信第三方实现一键登录及获取用户信息的方法
Oct 14 PHP
通过chrome浏览器控制台(Console)进行PHP Debug的方法
Oct 19 PHP
PHP获取数组中指定的一列实例
Dec 27 PHP
PHP实现生成模糊图片的方法示例
Dec 21 PHP
Laravel框架学习笔记之批量更新数据功能
May 30 PHP
php array_pop 删除数组最后一个元素实例
Nov 02 #PHP
PHP设置images目录不充许http访问的方法
Nov 01 #PHP
PHP递归获取目录内所有文件的实现方法
Nov 01 #PHP
php获得文件夹下所有文件的递归算法的简单实例
Nov 01 #PHP
ecshop适应在PHP7的修改方法解决报错的实现
Nov 01 #PHP
遍历echsop的region表形成缓存的程序实例代码
Nov 01 #PHP
CI框架无限级分类+递归的实现代码
Nov 01 #PHP
You might like
PHP脚本的10个技巧(4)
2006/10/09 PHP
phpcms手机内容页面添加上一篇和下一篇
2015/06/05 PHP
利用switch语句进行多选一判断的实例代码
2016/11/14 PHP
PHP中error_reporting函数用法详细介绍
2017/06/11 PHP
js如何判断不同系统的浏览器类型
2013/10/28 Javascript
浅谈JavaScript中运算符的优先级
2015/07/07 Javascript
浅谈JavaScript中的string拥有方法的原因
2015/08/28 Javascript
JS基于面向对象实现的拖拽库实例
2015/09/24 Javascript
解决js函数闭包内存泄露问题的办法
2016/01/25 Javascript
JS实现简单易用的手机端浮动窗口显示效果
2016/09/07 Javascript
jsonp跨域请求详解
2017/07/13 Javascript
js单页hash路由原理与应用实战详解
2017/08/14 Javascript
原生nodejs使用websocket代码分享
2018/04/07 NodeJs
jQuery实现点击图标div循环放大缩小功能
2018/09/30 jQuery
js+html5 canvas实现ps钢笔抠图
2019/04/28 Javascript
详解Vue-Router源码分析路由实现原理
2019/05/15 Javascript
JS立即执行的匿名函数用法分析
2019/11/04 Javascript
原生js+ajax分页组件
2020/01/30 Javascript
python自动化测试之连接几组测试包实例
2014/09/28 Python
python基于queue和threading实现多线程下载实例
2014/10/08 Python
bat和python批量重命名文件的实现代码
2016/05/19 Python
Python中使用platform模块获取系统信息的用法教程
2016/07/08 Python
Python文件操作,open读写文件,追加文本内容实例
2016/12/14 Python
Django 根据数据模型models创建数据表的实例
2018/05/27 Python
Python安装Flask环境及简单应用示例
2019/05/03 Python
如何使用Python 打印各种三角形
2019/06/28 Python
Python列表元素常见操作简单示例
2019/10/25 Python
Python和Sublime整合过程图示
2019/12/25 Python
django3.02模板中的超链接配置实例代码
2020/02/04 Python
python实现飞机大战项目
2020/03/11 Python
Python求凸包及多边形面积教程
2020/04/12 Python
一款恶搞头像特效的制作过程 利用css3和jquery
2014/11/21 HTML / CSS
管理专员自荐信
2014/01/26 职场文书
玄武湖导游词
2015/02/05 职场文书
家电创业计划书
2019/08/05 职场文书
SqlServer: 如何更改表的文件组?(进而改变存储位置)
2021/04/05 SQL Server