• <code id="58gs9"></code>

      <mark id="58gs9"></mark>
      1. 您好£¬欢迎来到源码搜藏网£¡分享精神£¬快乐你我£¡
        [加入VIP] 设为首页 | 收藏本站 | 网站地图 | Sitemap | TAG标签
      2. 首 页
      3. 在线工具
      4. jquery手册
      5. 当前位置£º首页 > 安卓源码 > 技术博客 >

        如何在Android中实现异步任务

        时间£º2019-02-28 22:49 来源£º互联网 作者£º源码搜藏 浏览£º收藏 挑错 推荐 打印

        在Android应用程序中£¬当我们需要与可能需要时间的外部资源£¨例如从外部API或数据库获取数据£©进行交互时£¬我们希望主UI保持交互并阻止UI线程在长时间运行的进程中运行很活跃¡£ 另请注意£¬默认情况下£¬不允许在Android的UI线程中运行网络任务¡£ 如果主线程用

        在Android应用程序中£¬当我们需要与可能需要时间的外部资源£¨例如从外部API或数据库获取数据£©进行交互时£¬我们希望主UI保持交互并阻止UI线程在长时间运行的进程中运行很活跃¡£另请注意£¬默认情况下£¬不允许在Android的UI线程中运行网络任务¡£

        如果主线程用于获取外部数据£¬则在获取数据时主UI将不会保持交互£¬并且如果数据获取过程遇到异常£¬则可能?#20801;?#24322;常行为¡£在这种情况下£¬android的异步任务变得很方便£¬尤其是使用后台线程更新UI的一部分¡£

        异步任务是将主线程的工作?#23545;?#21040;某个后台线程的几种方法之一¡£虽然AsyncTask不是唯一的选择£¬但这?#19988;?#20010;简单而且非常常见的选择¡£

        在开始之前£¬我想?#26790;使?#27468;的开发者页面包含的信息AsyncTaskhttps://developer.android.com/reference/android/os/AsyncTask审议有关实施一些内容AsyncTask秒¡£

        这个AsyncTask班?#19988;?#20010;abstract班级¡£实现通常是在UI线程上运行的类的子类¡££¨AsyncTask即子类£©的实现将覆盖至少一种方法£¬通常是两种方法¡£

        执行异步任务时£¬任务将执行4个步骤£¬如Android开发人员页面中所述£¬网址https://developer.android.com/reference/android/os/AsyncTask£º

        1. onPreExecute£¬在执行任务之前在UI线程?#31995;?#29992;¡£此步骤用于设置任务£¬例如通过在用户界面中?#20801;?#24494;调器¡£
        2. doInBackground(Params...£¬在完成执行后立即在后台线程?#31995;?#29992;¡£此步骤用于执行可能需要很长时间的后台计算¡£异步任务的参数将传递给此步骤¡£计算结果必须由此步骤返回£¬并将传递回最后一步¡£此步骤还可用于发布一个或多个进度单位¡£这些值发布在UI线程中steponProgressUpdate(Progress...)
        3. onProgressUpdate(Progress...£¬在调用publishProgress(Progress...步骤后在UI线程?#31995;?#29992;¡£执行的时间是不确定的¡£此方法用于在后台计算仍在执行时?#20801;?#29992;户界面中的任何形式的进?#21462;?/font>例如£¬它可用于为进度条设置动画或在文本字段中?#20801;?#26085;志¡£
        4. onPostExecute(Result)£¬在后台计算完成后在UI线程?#31995;?#29992;¡£背景计算的结果作为参数传递给该步骤¡£

        我将通过代码来?#24471;?#24037;作机制¡£代码来自我为Udacity的Android纳米学位课程所做的顶点项目¡£完整代码可在https://github.com/benktesh/Capstone-Project获得¡£在本演示中£¬我使用代码块中?#20801;?#30340;轻量级代码£¬如下所示£º

        package benktesh.smartstock;
        import android.app.ActivityOptions;
        import android.content.Intent;
        import android.os.AsyncTask;
        import android.os.Bundle;
        import android.support.design.widget.FloatingActionButton;
        import android.support.v7.app.AppCompatActivity;
        import android.support.v7.widget.LinearLayoutManager;
        import android.support.v7.widget.RecyclerView;
        import android.support.v7.widget.Toolbar;
        import android.util.Log;
        import android.view.Menu;
        import android.view.MenuItem;
        import android.view.View;
        import android.widget.ProgressBar;
        import android.widget.Toast;
        import java.util.ArrayList;
        import benktesh.smartstock.Model.Stock;
        import benktesh.smartstock.UI.CommonUIHelper;
        import benktesh.smartstock.UI.StockDetailActivity;
        import benktesh.smartstock.Utils.MarketAdapter;
        import benktesh.smartstock.Utils.NetworkUtilities;
        import benktesh.smartstock.Utils.PortfolioAdapter;
        import benktesh.smartstock.Utils.SmartStockConstant;
        
        public class MainActivity extends AppCompatActivity implements
                MarketAdapter.ListItemClickListener, PortfolioAdapter.ListItemClickListener {
        
            private static final String TAG = MainActivity.class.getSimpleName();
            CommonUIHelper mCommonUIHelper;
            ArrayList<Stock> mMarketData;
            private Toast mToast;
            //The following are for market summary
            private MarketAdapter mAdapter;
            private RecyclerView mMarketRV;
            private ProgressBar spinner;
        
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
                Toolbar toolbar = findViewById(R.id.toolbar);
                setSupportActionBar(toolbar);
        
                spinner = findViewById(R.id.progressbar);
        
                FloatingActionButton fab = findViewById(R.id.fab);
                fab.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
        
                        Intent Email = new Intent(Intent.ACTION_SEND);
                        Email.setType(getString(R.string.label_emailtype));
                        Email.putExtra(Intent.EXTRA_EMAIL,
                                new String[]{getString
                                   (R.string.label_developer_contat_email)});  //developer 's email
                        Email.putExtra(Intent.EXTRA_SUBJECT,
                                R.string.label_feedback_subject); // Email 's Subject
                        Email.putExtra(Intent.EXTRA_TEXT, 
                         getString(R.string.label_address_developer) + "");  //Email 's Greeting text
                        startActivity(Intent.createChooser(Email, getString(R.string.label_send_feedback)));
                    }
                });
        
                if (mCommonUIHelper == null) {
                    mCommonUIHelper = new CommonUIHelper(this);
                }
        
                mMarketRV = findViewById(R.id.rv_market_summary);
                LinearLayoutManager layoutManager = new LinearLayoutManager(this);
                mMarketRV.setLayoutManager(layoutManager);
                mMarketRV.setHasFixedSize(true);
                mAdapter = new MarketAdapter(mMarketData, this);
                mMarketRV.setAdapter(mAdapter);
                LoadView();
            }
        
            private void LoadView() {
                Log.d(TAG, "Getting Market Data Async");
                new NetworkQueryTask().execute(SmartStockConstant.QueryMarket);
            }
        
            private void MakeToast(String msg) {
                Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
            }
        
            public boolean onCreateOptionsMenu(Menu menu) {
                return mCommonUIHelper.ConfigureSearchFromMenu(menu);
        
            }
        
            @Override
            public boolean onOptionsItemSelected(MenuItem item) {
                // Handle action bar item clicks here. The action bar will
                // automatically handle clicks on the Home/Up button, so long
                // as you specify a parent activity in AndroidManifest.xml.
                if (mCommonUIHelper.MakeMenu(item)) return true;
                return super.onOptionsItemSelected(item);
            }
        
            @Override
            public void onListItemClick(Stock data) {
                if (mToast != null) {
                    mToast.cancel();
                }
                Intent intent = new Intent(this.getApplicationContext(), StockDetailActivity.class);
                intent.putExtra(SmartStockConstant.ParcelableStock, data);
                Bundle bundle = ActivityOptions.makeSceneTransitionAnimation(this).toBundle();
                startActivity(intent, bundle);
            }
        
            /*
            This is an async task that fetches data from network and new data is applied to adapter.
            Also makes a long toast message when fails to retrieve information from the network
            It takes void, void and returns ArrayList<?>
             */
            class NetworkQueryTask extends AsyncTask<String, Integer, ArrayList<Stock>> {
        
                private String query;
        
                @Override
                protected void onPreExecute() {
                    if (spinner != null) {
                        spinner.setVisibility(View.VISIBLE);
                    }
                }
        
                @Override
                protected ArrayList<Stock> doInBackground(String... params) {
                    query = params[0];
        
                    ArrayList<Stock> searchResults = null;
                    try {
        
                        searchResults = NetworkUtilities.getStockData(getApplicationContext(), query);
        
                        for (int i = 0; i <= 100; i = i + 25) {
                            Thread.sleep(500);
                            publishProgress(i);
                        }
        
                    } catch (Exception e) {
                        Log.e(TAG, e.toString());
                    }
                    return searchResults;
                }
        
                @Override
                protected void onProgressUpdate(Integer... progress) {
                    super.onProgressUpdate(progress);
                    Toast.makeText(getApplicationContext(), "Progress:  " + 
                                   progress[0] + "(%)", Toast.LENGTH_SHORT).show();
                }
        
                @Override
                protected void onPostExecute(ArrayList<Stock> searchResults) {
                    super.onPostExecute(searchResults);
        
                    if (searchResults != null && searchResults.size() != 0) {
                        mAdapter.resetData(searchResults);
                    }
        
                    if (spinner.getVisibility() == View.VISIBLE) {
                        spinner.setVisibility(View.GONE);
                    }
                }
            }
        }

        NetworkQueryTask 作为子实现的类MainActivity和子类扩展了Android的AsyncTask abstract类¡£子类可以定义如下£º

        private class NetworkQueryTask extends AsyncTask<T1, T2, T3> {...}
        

        T1£¬T2T3是参数的数据类型和他们每个人?#21152;?#19968;些特定的含义¡£

        上面定义的任务可以执行如下£º

        new NetworkAsyncTask().execute(param1);
        

        param1的类型与T1¡£的类型相同¡£

        MainActivity在UI线程运行¡£onCreate(..)'方法确实设置了UI¡£设置涉及为回收器视图等创建适配器£¬最后调用a LoadView£¨£©¡£LoadView£¨£©方法执行AsyncTask从网络获取数据和更新视图的适配器¡£

        在这样做的过程中£¬我们创建了一个NetworkQueryTask从中扩展的子类AsyncTask¡£该类有三个参数string£¬Void ArrayList<Stock>¡£股票?#19988;?#20010;存储信息的简单类Stock¡£一旦进程开始£¬我们希望我们可以在doInBackground£¨..£©方法中看到微调器¡£

        在上面的任务中£¬这三个参数表示用于的输入参数的类型doInBackground(T1 param1)£¬onProgressUpdate(T2 param2) onPostExecute(T3 param3)¡£doInBackground步骤完成执行时£¬param3将是doInBackground步骤的输出£¬并将成为该onPostExecute(param3)方法的输入¡£

        子类通常至少覆?#19988;?#31181;方法£¬最常见的是doInBackground(..)方法£¬也包括第二种方法£¬即onPostExecute()¡£onProgressUpdate onPreExecute()方法是可选的£¬可以跳过¡£因此£¬如果没有关于进度更新的任何事情£¬那么就不需要覆盖onProgressUpdate £¬然后param2 可以Void 在类定义本身中使用类型¡£例如£¬假设需要将string参数传递doInBackground£¨£©而不需要onProgressUpdate()方法£¬并且该onPostExecute()方法接受一个string参数£¬那么类定义将如下所示£º

        private class NetworkQueryTask extends AsyncTask<String, Void, String> {...}
        

        因此£¬我们可?#36816;?#36825;三个参数分别代表输入doInBackground£¬输入onProgressUpdate()和输入onPostExecute¡£输出的参数类型doInBackground与输入相同onPostExectute()¡£此外£¬如果async任务是作为火灾而忘记诸如触发某事£¬那么所有参数都可以void¡£例如£¬在这种情况下£¬子类的定义如下所示£º

        private class NetworkQueryTask extends AsyncTask<Void, Void, Void> {...}
        

        上面的类执行如下£º

        new NetworkAsyncTask().execute();
        

        AsyncTasks不知道应用程序中的其他活动£¬因此必须在销毁活动时正确处理¡£因此£¬AsycnTask不适合长时间运行的操作£¬因为如果应用程序在后台运行£¬当Android的终止调用该应用程序AsyncTask时£¬AsyncTask不被打死£¬我们必须管理的如何处理的结果做处理AsyncTask¡£因此£¬AsyncTasks在获取不长时间运行的数据时很有用¡£还有其他替代AyscTask它们IntentServices£¬LoaderJobScheduler许多基于Java的实现¡£

        如何在Android中实现异步任务转载
        ´ó¸»ÎÌÆåÅÆÓéÀÖ¹ÙÍø

      6. <code id="58gs9"></code>

          <mark id="58gs9"></mark>

          1. <code id="58gs9"></code>

              <mark id="58gs9"></mark>