使用jsoup时最好的后台处理方式,asynctask问题

时间:2016-07-09 03:54:10

标签: android multithreading android-asynctask jsoup asynctaskloader

我想从网站上获取一些数据,我正在使用jsoup。但是有一个问题,当我在asynctask中使用jsoup它工作得很好但我通过导航视图进入这个过程当我点击它开始的项目,但导航视图没有关闭,进度条不工作,所以我不知道该怎么办。

问题是:

我应该尝试使用不同的方法,如(threads,asynctaskloader等),还是有办法防止这些问题。

这是片段的onCreateView方法:

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
{
    View rootView = inflater.inflate(R.layout.tab_fragment_container, container, false);



    newspapers = readFromFile("20 Name.txt");
    newspapersPath = readFromFile("20 Path.txt");



    FetchingInstantNews fetchingInstantNews = new FetchingInstantNews((AppCompatActivity)getActivity(),newspapers,newspapersPath);

    try
    {
        cardItems = fetchingInstantNews.execute().get();
    }
    catch (Exception ex)
    {
        ex.printStackTrace();
    }


    mRecylerView = (RecyclerView)rootView.findViewById(R.id.recyclerView);
    setupRecyclerView(mRecylerView);

    return rootView;
}

这是我的asynctask类:

public class FetchingInstantNews   extends  AsyncTask<Void,Void,ArrayList<CardItem>>
{
private String[] newspapers,newspapersPath;

private AppCompatActivity activity;
private ProgressDialog progressDialog;

private Document doc,innerDoc;
private Elements[] elementses = new Elements[14];

private static String site,innerSite;

public FetchingInstantNews(AppCompatActivity activity,String[] newspapers,String[] newspapersPath)
{
    this.newspapers = newspapers;
    this.newspapersPath = newspapersPath;
    this.activity = activity;
}

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

    progressDialog = new ProgressDialog(activity);
    progressDialog.setTitle("Haberler");
    progressDialog.setMessage("Haberleriniz Hazırlanıyor..");
    progressDialog.setIndeterminate(false);

}

@Override
protected ArrayList<CardItem> doInBackground(Void... voids)
{
    ArrayList<CardItem> cardViews = new ArrayList<>();

    for(int i=0;i<newspapers.length;i++)
    {

        site = newspapersPath[i];

        try
        {
            doc = Jsoup.connect(site).timeout(120*1000)
                    .userAgent("Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:25.0) Gecko/20100101 Firefox/25.0")
                    .referrer("http://www.google.com")
                    .get();

            elementses[0] = doc.select("div[class=wrapper-new]");
            elementses[1] = elementses[0].select("section[id=top]");
            elementses[2] = elementses[1].select("section[class=manset-wrap c]");
            elementses[3] = elementses[2].select("div[class=site-box box box-list]");
            elementses[4] = elementses[3].select("div[class=us]");
            elementses[5] = elementses[4].select("div[class=sol]");
            elementses[6] = elementses[5].select("div[class=manset]");
            elementses[7] = elementses[6].select("div[class=m-item]");
            elementses[8] = elementses[7].select("article");

            int perCount=0;

            for (Element articleItem : elementses[8])
            {

                if(perCount >= 3)
                {
                    break;
                }

                CardItem cardItem = new CardItem();

                elementses[9] = articleItem.select("a");

                cardItem.setPubDate(elementses[9].select("meta[itemprop=datePublished]").attr("content")); //Date
                cardItem.setDescription(elementses[9].select("meta[itemprop=headline]").attr("content")); // desc
                cardItem.setThumbnailUrl(elementses[9].select("img").attr("data-src")); // thumb



                try
                {

                    elementses[10] = elementses[6].select("nav");
                    elementses[11] = elementses[10].select("div[class=sol]").select("span");

                    cardItem.setName(elementses[11].text().replace("Son","")); // title

                }
                catch (Exception ex)
                {
                    ex.printStackTrace();
                }

                try
                {
                    innerSite = elementses[9].attr("href");

                    innerDoc = Jsoup.connect(innerSite).timeout(100*1000)
                            .userAgent("Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:25.0) Gecko/20100101 Firefox/25.0")
                            .referrer("http://www.google.com")
                            .get();

                    elementses[12] = innerDoc.select("div[class=flexwrap]");
                    elementses[13] = elementses[12].select("iframe");

                    cardItem.setPath(elementses[13].attr("src"));

                }
                catch (Exception ex)
                {
                    ex.printStackTrace();
                }


                perCount++;


                cardViews.add(cardItem);
            }
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }
    }

    return cardViews;
}

@Override
protected void onPostExecute(ArrayList<CardItem> aVoid)
{
    progressDialog.dismiss();
    super.onPostExecute(aVoid);
}
}

这是我的主要活动:

private Toolbar mToolbar;
private DrawerLayout mDrawerLayout;
private NavigationView mNavigationView;
private ActionBarDrawerToggle mActionBarDrawerToggle;
private RelativeLayout mStockLayout;
private TabLayout mTabLayout;
private FragmentManager mFragmentManager;
private FragmentTransaction mFragmentTransaction;


@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mToolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(mToolbar);

    getSupportActionBar().setHomeButtonEnabled(true);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    mFragmentManager = getSupportFragmentManager();
    mFragmentTransaction = mFragmentManager.beginTransaction();

    mDrawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout);



    mNavigationView = (NavigationView) findViewById(R.id.navigation_view);

    if (mNavigationView != null)
    {
        setupDrawerContent(mNavigationView);
    }


    mActionBarDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, mToolbar, R.string.app_name, R.string.app_name) {

        @Override
        public void onDrawerOpened(View drawerView)
        {
            super.onDrawerOpened(drawerView);
        }

        @Override
        public void onDrawerClosed(View drawerView)
        {
            super.onDrawerClosed(drawerView);
        }
    };


    mFragmentTransaction.replace(R.id.frame,new TabFragmentsContainer());

    mDrawerLayout.setDrawerListener(mActionBarDrawerToggle);

    mActionBarDrawerToggle.syncState();

}

private void setupDrawerContent(NavigationView navigationView)
{
    navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener()
    {
        @Override
        public boolean onNavigationItemSelected(MenuItem menuItem)
        {
            menuItem.setChecked(true);

            switch (menuItem.getItemId())
            {
                case R.id.anasayfa:

                    mDrawerLayout.closeDrawers();
                    changeFragment(new FragmentsContainer(),true);

                    break;
                case R.id.anlık:
                    if(mDrawerLayout.isDrawerOpen(mNavigationView))
                    {
                        mDrawerLayout.closeDrawer(mNavigationView);

                    }
                    else
                    {
                        mDrawerLayout.openDrawer(mNavigationView);
                    }

                    changeFragment(new TabFragmentsContainer(),false);
                    break;
                case R.id.ilkler:
                    Log.d("Frag","İlkler");
                    break;
                case R.id.ulusal:
                    Log.d("Frag","Ulusal");
                    break;
            }



            return true;
        }
    });
}

提前致谢!

1 个答案:

答案 0 :(得分:0)

在这里,你真的不应该使用你的AsyncTaskget()get()方法将阻止您的UI线程,这可能是您的进度条未显示且导航抽屉未关闭的原因。

相反,您应该实施回调机制,即告诉您的AsyncTask在任务完成时回电。以下是您案例的示例:

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
{
    View rootView = inflater.inflate(R.layout.tab_fragment_container, container, false);

    newspapers = readFromFile("20 Name.txt");
    newspapersPath = readFromFile("20 Path.txt");

    FetchingInstantNews fetchingInstantNews = new FetchingInstantNews((AppCompatActivity)getActivity(),newspapers,newspapersPath);

    try
    {
        fetchingInstantNews.execute(); // do not call get()
    }
    catch (Exception ex)
    {
        ex.printStackTrace();
    }

    cardItems = new ArrayList<CardItems>(); // initialise recycler view with an empty list for now, because AsyncTask will not finish before you setup RecyclerView.
    mRecylerView = (RecyclerView)rootView.findViewById(R.id.recyclerView);
    setupRecyclerView(mRecylerView);

    return rootView;
}

// This method is called AFTER asynctask is finished
public void stepsAfterAsyncTask(ArrayList<CardItem> result)
{
    cardItems = result;
    // Re-initialise adapter with result data
    mRecylerView = (RecyclerView)rootView.findViewById(R.id.recyclerView);
    setupRecyclerView(mRecylerView);
    // make sure you notify adapter to use the new cardItems
    mRecylerView.getAdapter().notifyDataSetChanged();
}

您的AsyncTask:

public class FetchingInstantNews   extends  AsyncTask<Void,Void,ArrayList<CardItem>>
{
private String[] newspapers,newspapersPath;

//....
//....

@Override
protected void onPostExecute(ArrayList<CardItem> result)
{
    activity.stepsAfterAsyncTask(result); // call back your activity with the result
    progressDialog.dismiss();
    super.onPostExecute(result);
}
}

我不知道您的setupRecyclerView方法是什么样的,所以您需要根据自己的需要进行更改。