zoukankan      html  css  js  c++  java
  • Android精通之AsyncTask与ListView讲解

    版权声明:未经博主允许不得转载

    AsyncTask

    了解AsyncTask异步,需要了解一下异步任务(多线程),什么是线程,可以这么说线程好比边吃饭边看电视,AsyncTask是为了方便后台线程中操作更新UI,本质为Handler异步消息处理机制。

    学习AsyncTask需要知道它的参数<Params,Progress,Result>,它要实现的方法onPreExcecute(),onPostExecute(),后台线程操作doInBackground();显示进度onProgressUpdate()等方法。在这里混个眼熟,下面会用代码讲一下如何用。

    在这里我们创建一个类

    public class MainActivity extends AppCompatActivity {
     @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
        }
     //这里创建一个内部类继承AsyncTask
     public class DownloadAsyncTask extends AsyncTask<String,Integer,Boolean>{
    
     }
    
    }

    我们在这里点击去看底层AsyncTask

    public abstract class AsyncTask<Params, Progress, Result> {
    //其中Params为类型参数,Progress为进度,为返回结果
    }

    在这里继承,实现的方法有

    //在异步任务之前
    @Override
    protected void onPreExecute() {
         super.onPreExecute();
         // 准备工作
               
    }
    
    @Override
    protected Boolean doInBackground(String... strings){
     //处理事件
    }
    
    @Override
    protected void onPostExecute(Boolean aBoolean){
     super.onPostExecute(aBoolean);
     //执行完,执行结果 处理
    }
    
    //当我们的进度在变化的时候
    @Override
     protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
         //收到进度,然后处理:也是在UI线程中。
    }
    
    //取消
    /*@Override
    protected void onCancelled(Boolean aBoolean) {
         super.onCancelled(aBoolean);
    }
    
    @Override
    protected void onCancelled() {
        super.onCancelled();
    }*/

    在这里通常执行onPreExcecute(执行前),doInBackground(执行中),onPostExecute(执行后),onProgressUpdate这些方法。

    在这里写个例子,如何下载一个从网络上下载一个apk,请求网络数据下载文件。在这里我会比较详细地讲解一下如何获取url,以及请求网络的事情。

    设置一个点击下载文件的按钮

    //定义一个方法
    private void setButtonListener(){
     mDownloadButton.setOnClickListener(new View.OnClickListener() {
               @Override
               public void onClick(View v) {
                   DownloadAsyncTask asyncTask = new DownloadAsyncTask();
                   asyncTask.execute(APK_URL);
                }
        });
    }
    在这里讲解一下,申请asyncTask应用可以理解,就是在创建对象嘛,public class DownloadAsyncTask extends AsyncTask<String,Integer,Boolean>{...},那么这个'execute'还没讲,那就点击进入看一下源码吧~

    @MainThread
    public final AsyncTask<Params, Progress, Result> execute(Params... params) {
           return executeOnExecutor(sDefaultExecutor, params);
    }
    //通过execute实现

    下面就进入执行中的代码

    //解释一下这里的Boolean是由这个定义的
    public class DownloadAsyncTask extends AsyncTask<String,Integer,Boolean>{
    }
    
    //<Params, Progress, Result>
    //String... strings 表示数组,可变参数,可能为空
    @Override
    protected Boolean doInBackground(String... strings){
    
    }

    执行前

    @Override
    protected void onpreExecute(){
      super.onPreExecute();
     //解决UI问题
    }

    执行中的代码,进行下载:

    //String... 为数组
    @Override
    protected Boolean doInBackground(String... strings) {
      //预防为空
      if (strings != null && strings.length>0){
         //传入的参数是url,由上面的
         // DownloadAsyncTask asyncTask = new DownloadAsyncTask();
         //asyncTask.execute(APK_URL);
         //决定
         String apkurl = strings[0];
         try{
          //给你一个下载地址url,那么你就要创建一个url对象
          URL url = new URL(apkurl);//String apkurl = strings[0];
          //构造一个URLConnection 打开连接 url.openConnection()
          URLConnection urlConnection = url.openConnection();
    
         //输入流 读取数据
         InputStream inputStream = urlConnection.getInputStream();
         //接下来获取下载内容的总长度
         int contentLength = urlConnction.getContentLength();
    
         //接下来就是找个地方存放,就跟放在目录哪里一下,为字符串
         String mFilePath=Environment.getExternalStorageDirectory() + File.separator + FILE_NAME;
    // Environment.getExternalStorageDirectory() 为目录,比较实用
    // File.separator 相当'//'
    // FILE_NAME为文件名,可改为“what.apk”.
    
    //对下载地址进行处理
    
    File apkFile = new File(mFilePath);
    //接下来就是文件输入到目录中
    //先读取再写入
    //判断文件
    if(apkFile.exists()){
     boolean result = apkFile.delete();
    
     if(!result){
      return false;
     }
    
    }
    
    //文件进度条,已经下载了多少
    int downloadSize = 0;
    
    //定义一个读取数组长度,接下来进行。。。
    byte[] bytes = new byte[1024];//1024没有规定,可以自己决定
    //读取多长
    int length;
    //创建一个输出流,写
    OutputStream outputStream = new FileOutputStream(mFilePath);//写到这个路径
    
    while(  (length = inputStream.read(bytes)) != -1){
     outputStream.write(bytes,0,length);
     downloadSize+=length;
     //发送进度
     publishProgress();
    }
    ....
      }
    }

    执行后

    @Override
    protected void onPostExecute(Boolean aBoolean) {
     super.onPostExecute(aBoolean);
     //也是在主线程中,执行结果 处理
     //处理UI
    }

    最后进度变化

    //当我们的进度在变化的时候
    @Override
    protected void onProgressUpdate(Integer... values) {
     super.onProgressUpdate(values);
     if (values != null && values.length >0){
     }
    }

    重点要添加网络权限以及读取权限

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

    ListView

    ListView是我们在Android开发中常用到的一个控件,用来展示数据,我们在微信列表项,文章列表随处可见。

    深入了解

    public class AppListAdapter extends BaseAdapter{}
    
    public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter {}
    
    public interface ListAdapter extends Adapter {}
    
    public interface SpinnerAdapter extends Adapter {}
    创建布局
    <ListView
     android:id="@+id/main_list_view"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
    </ListView>
    实现控件声明

    private ListView mListView;
    mListView=findViewById(R.id.main_list_view);
    步骤:了解一下Adapter(适配器)
    public class AppListAdapter extends BaseAdapter{
    }
    //获取包名
    String packageName = mAppInfos.get(position).activityInfo.packageName;
    ////获取应用名
    String className = mAppInfos.get(position).activityInfo.name;
    //拼接-点击方法
    ComponentName componentName = new ComponentName(packageName,className);
    final Intent intent = new Intent();
    //通过Intent设置组件名
    intent.setComponent(componentName);
    startActivity(intent);

    BaseAdapter中抽象方法

    public int getCount();
    public Object getItem(int arg0);
    public long getItemId(int arg1);
    public View getView(int position, View convertView, ViewGroup parent);
    public View getView(int position, View covertView, ViewGroup parent){
     if(converView == null){
       converView = mInflater.inflate(R.layout.list_item, null);
      }
    }
    static class ViewHolder{
     public ImageView image;
     public TextView title;
    }
    
    @Override
    public View getView(int position,view convertView, ViewGroup parent){
     ViewHolder holder;
    
     if(convertView == null){
      holder = new ViewHolder();
      convertView = mInflater.inflate(R.layout.list_item, null);
      holder.
      holder.
       convertView.setTag(holder);
     }else{
       holder=(ViewHolder)convertView.getTag();
     }
    
    }
    定位:分享 Android&Java 知识点


  • 相关阅读:
    GPU 版 TensorFlow failed to create cublas handle: CUBLAS_STATUS_ALLOC_FAILED
    Python -- 值转换为字符串的两种机制
    Python
    vim中注释多行python代码
    HTTP协议状态码详解(HTTP Status Code)
    关于Python报错:SyntaxError: Non-ASCII character 'xe5' in file的解决方法
    Linux如何查看进程、杀死进程、启动进程等常用命令
    vim 如何设置显示行号和缩进
    一、报错
    二、极光推送
  • 原文地址:https://www.cnblogs.com/dashucoding/p/11932611.html
Copyright © 2011-2022 走看看