在 tablayout 中创建了一个 gridview 并尝试使用 Intent 服务更新 Gridview

Created a gridview in a tablayout and try to update Gridview with a Intent service

我在 Activity 中创建了一个选项卡式布局。我的 Activity 作为以下考虑点
1. 选项卡的数量取决于源对象可用的排序类型。最多可以有三个选项卡,即热门、最新和流行。
2. 每个选项卡包含一个GridView 并且应该在IntentService 获取数据时更新
3. 用户可以从工具栏中选择来源
4.选择新源时,应该根据新源的选项卡数量,并且GridView也应相应地更新

标签式Activity

public class TabbedActivity extends AppCompatActivity {

private Toolbar toolbar;
private TabLayout tabLayout;
private ViewPager mViewPager;

private List<Source> allSourceItem;

private Context context;

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

    context = this;

    // register broadcast
    IntentFilter statusIntentFilter = new IntentFilter(Asset.ARTICLE_BROADCAST_ACTION);
    TabbedActivity.ArticleStateReceiver mDownloadStateReceiver = new TabbedActivity.ArticleStateReceiver();
    LocalBroadcastManager.getInstance(this).registerReceiver(mDownloadStateReceiver, statusIntentFilter);

    // set toolbar
    toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    // set tab layout
    tabLayout = (TabLayout) findViewById(R.id.tab_layout);

    // set the viewpager
    mViewPager = (ViewPager) findViewById(R.id.container);

    // set up page listner to viewpager
    mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
    tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            mViewPager.setCurrentItem(tab.getPosition());
        }

        @Override
        public void onTabUnselected(TabLayout.Tab tab) {

        }

        @Override
        public void onTabReselected(TabLayout.Tab tab) {

        }
    });

    startSetUp(getRecentDisplayedData());

}

public void startSetUp(Source src){

    int tabsCount = 3;

    setTitle(src.getName());
    tabsCount = getNumberOfTabs(src.getSortByAvailableTop(),src.getSortByAvailableLatest(),src.getSortByAvailablePopular());

    setTabs(tabsCount);
    tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);

    mViewPager.setAdapter(new SectionsPagerAdapter(getSupportFragmentManager(),tabsCount,src));

}

// handle menus of activity
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu_tabbed, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();

    if (id == R.id.action_settings) {
        Intent intent = new Intent(this, SourcesActivity.class);
        intent.putExtra("SOURCE_ACTIVITY_ACTION","TABBED");
        startActivity(intent);
        return true;
    }

    if(id == R.id.change_src){
        //get all selected sources
        allSourceItem = Source.getAll();
        List<String> listItems = new ArrayList<String>();
        for(int i = 0; i < allSourceItem.size(); i++ ){
            listItems.add(allSourceItem.get(i).getName());
        }

        final CharSequence[] items = listItems.toArray(new CharSequence[listItems.size()]);

        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(R.string.chnage_news_source);
        builder.setItems(items, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int item) {
                Source.updateRecentDisplayed(allSourceItem.get(item));
                restartActivity();
            }
        });
        AlertDialog alert = builder.create();
        alert.show();
    }

    return super.onOptionsItemSelected(item);
}

// for creatting tabs Fragments
public static class PlaceholderFragment extends Fragment {
    /**
     * The fragment argument representing the section number for this
     * fragment.
     */

    private GridView mGridView;
    private ArticleAdapter mArticleAdapter;
    private ArrayList<Article> mGridData = new ArrayList<Article>();
    private TextView tv;

    private static final String ARG_SECTION_NUMBER = "section_number";

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    public PlaceholderFragment() {
    }

    /**
     * Returns a new instance of this fragment for the given section
     * number.
     */
    public static PlaceholderFragment newInstance(int sectionNumber) {
        PlaceholderFragment fragment = new PlaceholderFragment();
        Bundle args = new Bundle();
        args.putInt(ARG_SECTION_NUMBER, sectionNumber);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_tabbed, container, false);
        tv = (TextView) rootView.findViewById(R.id.test_tv);
        tv.setText("Page counter :: "+getArguments().getInt(ARG_SECTION_NUMBER));
        mGridView = (GridView) rootView.findViewById(R.id.article_grid);
        update(mGridData);
        return rootView;
    }

    public void update(ArrayList<Article> data){
        mArticleAdapter = new ArticleAdapter(getContext(),R.layout.aricle_grid_element,data);
        mGridView.setAdapter(mArticleAdapter);
    }

}

public class SectionsPagerAdapter extends FragmentPagerAdapter {

    int tabsCount;
    Source src;
    public SectionsPagerAdapter(FragmentManager fm, int tabsCount, Source src) {
        super(fm);
        this.tabsCount = tabsCount;
        this.src = src;
    }


    @Override
    public Fragment getItem(int position) {
        // getItem is called to instantiate the fragment for the given page.
        // Return a PlaceholderFragment (defined as a static inner class below).

        if( position == 0){
            runArticleService(position+1);
            return PlaceholderFragment.newInstance(position + 1);
        }else if (position == 1){
            runArticleService(position+1);
            return PlaceholderFragment.newInstance(position + 1);
        }else if (position == 2){
            runArticleService(position+1);
            return PlaceholderFragment.newInstance(position + 1);
        }
        return null;
    }

    @Override
    public int getCount() {
        // Show 3 total pages.
        return tabsCount;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        switch (position) {
            case 0:
                return "SECTION 1";
            case 1:
                return "SECTION 2";
            case 2:
                return "SECTION 3";
        }
        return null;
    }

    private void runArticleService(int tabNumber){
        Intent mServiceIntent = new Intent(getBaseContext(), ArticleService.class);
        mServiceIntent.setData(Uri.parse(Asset.getSourceArticleURL(src.getUniqueId(),tabNumber)));
        startService(mServiceIntent);
    }
}

// broadcast receivers handle
private class ArticleStateReceiver extends BroadcastReceiver
{
    private ArticleStateReceiver() {

    }
    // Called when the BroadcastReceiver gets an Intent it's registered to receive
    @Override
    public void onReceive(Context context, Intent intent) {
        String response = intent.getStringExtra(Asset.ARTICLE_EXTENDED_DATA_TYPE);
        String sortType = intent.getStringExtra(Asset.ARTICLE_EXTENDED_DATA_SORT);

        if(sortType.equals("TOP")){
            SectionsPagerAdapter sectionsPagerAdapter = (SectionsPagerAdapter) mViewPager.getAdapter();
            PlaceholderFragment placeholderFragment = (PlaceholderFragment) sectionsPagerAdapter.getItem(0);
            placeholderFragment.update(Asset.getArticleObjectFromJSON(response.toString()));
        }else if(sortType.equals("LATEST")){
            SectionsPagerAdapter sectionsPagerAdapter = (SectionsPagerAdapter) mViewPager.getAdapter();
            PlaceholderFragment placeholderFragment = (PlaceholderFragment) sectionsPagerAdapter.getItem(1);
            placeholderFragment.update(Asset.getArticleObjectFromJSON(response.toString()));
        }else if(sortType.equals("POPULAR")){
            SectionsPagerAdapter sectionsPagerAdapter = (SectionsPagerAdapter) mViewPager.getAdapter();
            PlaceholderFragment placeholderFragment = (PlaceholderFragment) sectionsPagerAdapter.getItem(2);
            placeholderFragment.update(Asset.getArticleObjectFromJSON(response.toString()));
        }

    }
}

// Extra methods
private int getNumberOfTabs(boolean top, boolean latest, boolean popular ){
    if( top && latest && popular){
        return 3;
    }else if( top && latest && !popular ){
        return 2;
    }else if( top && !latest && !popular ){
        return 1;
    }else{
        return 1;
    }
}

private void setTabs(int tabCount){
    tabLayout.removeAllTabs();
    if(tabCount == 3){
        tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.tab_1_text)));
        tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.tab_2_text)));
        tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.tab_3_text)));
    }
    if(tabCount == 2){
        tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.tab_1_text)));
        tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.tab_2_text)));
    }
    if(tabCount == 1){
        tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.tab_1_text)));
    }
}

private Source getRecentDisplayedData(){
    Source src = Source.getRecentDisplayed();
    if(src!=null){
        return src;
    }else{
        src = Source.getRandom();
        Source.updateRecentDisplayed(src);
        return Source.getRecentDisplayed();
    }
}

public void restartActivity(){
    Intent myIntent = new Intent(this, TabbedActivity.class);
    startActivity(myIntent);
    finish();
}

}

IntentService

public class ArticleService extends IntentService {

public String responseStr = null;
public String urlStr = null;

public ArticleService() {
    super("ArticleService");
}

@Override
protected void onHandleIntent(Intent intent) {
    Uri url = intent.getData();
    urlStr = url.toString();
    responseStr = Asset.fetchSourceDataFromURL(urlStr);
    sendBroadcast();
}

protected void sendBroadcast(){
    Intent localIntent = new Intent(Asset.ARTICLE_BROADCAST_ACTION).putExtra(Asset.ARTICLE_EXTENDED_DATA_TYPE,responseStr);
    if(urlStr.toLowerCase().contains(Asset.SORT_TOP_URL.toLowerCase())){
      localIntent.putExtra(Asset.ARTICLE_EXTENDED_DATA_SORT,"TOP");
    }else if (urlStr.toLowerCase().contains(Asset.SORT_LATEST_URL.toLowerCase())){
        localIntent.putExtra(Asset.ARTICLE_EXTENDED_DATA_SORT,"LATEST");
    }else if (urlStr.toLowerCase().contains(Asset.SORT_POPULAR_URL.toLowerCase())){
        localIntent.putExtra(Asset.ARTICLE_EXTENDED_DATA_SORT,"POPULAR");
    }
    LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent);
}

}

我无法理解的错误

01-26 07:57:29.789 1494-1494/in.co.yogender.newsnick.newsnick E/AndroidRuntime: FATAL EXCEPTION: main
Process: in.co.yogender.newsnick.newsnick, PID: 1494
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.content.Context.getSystemService(java.lang.String)' on a null object reference
at android.view.LayoutInflater.from(LayoutInflater.java:232)
at android.widget.ArrayAdapter.<init>(ArrayAdapter.java:181)
at android.widget.ArrayAdapter.<init>(ArrayAdapter.java:166)
at in.co.yogender.newsnick.newsnick.Adapters.ArticleAdapter.<init>(ArticleAdapter.java:0)
at in.co.yogender.newsnick.newsnick.TabbedActivity$PlaceholderFragment.update(TabbedActivity.java:197)
at in.co.yogender.newsnick.newsnick.TabbedActivity$ArticleStateReceiver.onReceive(TabbedActivity.java:273)
at android.support.v4.content.LocalBroadcastManager.executePendingBroadcasts(LocalBroadcastManager.java:297)
at android.support.v4.content.LocalBroadcastManager.access[=11=]0(LocalBroadcastManager.java:46)
at android.support.v4.content.LocalBroadcastManager.handleMessage(LocalBroadcastManager.java:116)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)

提前致谢

我认为,您正在从 Context 为 null 的 IntentService 更新 GridView。尝试像下面这样从 IntentService 中提取上下文并告诉我。

public void update(Context cont, ArrayList<Article> data){
    mArticleAdapter = new ArticleAdapter(cont, R.layout.aricle_grid_element,data);
    mGridView.setAdapter(mArticleAdapter);
}