【问题标题】:The best background processing way while using jsoup,problems with asynctask使用jsoup时最好的后台处理方式,asynctask的问题
【发布时间】:2016-07-09 03:54:10
【问题描述】:

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

问题是:

我应该尝试使用不同的方法,例如(线程、异步任务加载器等)还是有办法防止这些问题。

这是我的片段的 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;
}

这是我的异步任务类:

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;
        }
    });
}

提前致谢!

【问题讨论】:

  • 对不起,也许不是 asynctask 你的问题,正如你所说的,“它运作良好”。我在 asynctask 中使用 jsoup,它还不错。尝试重新思考、重新规划、重新设计您的导航模型,看看人们在像您这样的情况下正在做什么。最好的。
  • 我尝试在没有导航视图的情况下使用 asynctask。Asynctask 和进度条都可以工作。但是,当我尝试打开包含异步任务的片段以通过导航视图项获取数据时,导航视图未关闭,进度条未显示仅屏幕冻结。当过程完成后它恢复正常。所以我无法理解我该怎么办。谢谢你的评论!
  • 哦,我现在明白你的困难了,对不起。让我们为你想办法。我建议您编辑您的答案并提供代码的一些关键部分供全世界查看。当然,您将从社区中获得见解。谢谢。

标签: android multithreading android-asynctask jsoup asynctaskloader


【解决方案1】:

事情是这样的,你真的不应该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();
}

你的异步任务:

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 方法是什么样的,所以你需要根据你的需要进行更改。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-21
    • 2021-06-09
    • 1970-01-01
    相关资源
    最近更新 更多