您当前的位置: 首页 >  android

寒冰屋

暂无认证

  • 1浏览

    0关注

    2286博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

在Android中实现异步任务

寒冰屋 发布时间:2019-02-20 20:20:37 ,浏览量:1

如何在Android中实现异步任务

介绍

在Android应用程序中,当我们需要与可能需要时间的外部资源(例如从外部API或数据库获取数据)进行交互时,我们希望主UI保持交互,并在长时间运行的进程处于活动状态时阻止UI线程工作。另请注意,默认情况下,不允许在Android的UI线程中运行网络任务。

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

异步任务是将主线程的工作卸载到某个后台线程的几种方法之一。虽然AsyncTask不是唯一的选择,但这是一个简单而且非常常见的选择。

在开始之前,我想访问谷歌的开发者页面,其包含有关AsyncTask的信息,网址:https://developer.android.com/reference/android/os/AsyncTask,以查看和实现AsyncTask有关的一些内容。

这个AsyncTask类是一个abstract类。实现通常是在UI线程上运行的类的子类。AsyncTask的实现,即子类,将覆盖至少一种方法,通常是两种方法。

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

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

我将通过代码来说明工作机制。代码来自我为Udacity的Android纳米学位课程所做的顶点项目。完整代码可在https://github.com/benktesh/Capstone-Project获得。在本演示中,我使用代码块中显示的轻量级代码,如下所示:

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 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 {

        private String query;

        @Override
        protected void onPreExecute() {
            if (spinner != null) {
                spinner.setVisibility(View.VISIBLE);
            }
        }

        @Override
        protected ArrayList doInBackground(String... params) {
            query = params[0];

            ArrayList searchResults = null;
            try {

                searchResults = NetworkUtilities.getStockData(getApplicationContext(), query);

                for (int i = 0; i             
关注
打赏
1665926880
查看更多评论
0.0472s