获取IndexOutOfBoundException:无效的数组范围0到0,所以context = null,所以App崩溃

时间:2016-06-29 19:44:24

标签: android android-asynctask interstitial

使用InterstitialAd练习, onClick 按钮,调用tellJoke()。 tellJoke()调用AsyncTask。 在AsyncTask中, params size为0,得到IndexOutOfBundException,因此context为null。

MainActivity.java

公共类MainActivity扩展了AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Log.d(LOG_TAG, "after setting activity main");

}

 public static void tellJoke(View view){          
    new EndpointsAsyncTask().execute();
 }
}

MainActivityFragment.java

 public class MainActivityFragment extends Fragment {

  InterstitialAd mInterstitialAd;

  public MainActivityFragment() {
  }

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

    AdView mAdView = (AdView) root.findViewById(R.id.adView);
            AdRequest adRequest = new AdRequest.Builder()
            .addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
            .build();
    mAdView.loadAd(adRequest);
    //interstitialAd part starts here
    mInterstitialAd = new InterstitialAd(getActivity());
    mInterstitialAd.setAdUnitId("ca-app-pub-3940256099942544/1033173712");

    mInterstitialAd.setAdListener(new AdListener() {
        @Override
        public void onAdClosed() {
            requestNewInterstitial();
            MainActivity.tellJoke(getView());
        }
    });
    return root;
}

private void requestNewInterstitial() {
    AdRequest adRequest = new AdRequest.Builder()
            .addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
            .build();

    mInterstitialAd.loadAd(adRequest);
 }
}

EndpointsAsyncTask.java

public class EndpointsAsyncTask extends AsyncTask<Context, Void, String> {

private static String LOG_TAG = EndpointsAsyncTask.class.getSimpleName();

private static MyApi myApiService = null;
private Context context ;

@Override
protected String doInBackground(Context... params) {

    if(myApiService == null) {  // Only do this once
        MyApi.Builder builder = new MyApi.Builder(AndroidHttp.newCompatibleTransport(),
                new AndroidJsonFactory(), null)
            .setRootUrl("https://build-it-bigger.appspot.com/_ah/api/");
        // end options for devappserver
        myApiService = builder.build();
    }       

    if (params != null) {
        context = params[0];
    }
    try {            
        return myApiService.fetchJoke().execute().getData();
    } catch (IOException e) {
        return e.getMessage();
    }
}

@Override
protected void onPostExecute(String result) {        
    if (context != null) {
        Intent intent = new Intent(context, JokeDisplayActivity.class);
        intent.putExtra(Intent.EXTRA_TEXT, result);
        context.startActivity(intent);
    }
}}
请帮助,我在哪里做错了?如果有其他方法,请建议。

1 个答案:

答案 0 :(得分:1)

当您调用execute时,只需为AsyncTask提供参数(同时删除静态):

public void tellJoke(View view){          
   new EndpointsAsyncTask().execute(getActivity());
}

this引用活动,从而实现Context接口(如果从活动中调用)。

修改: 将您的tellJoke方法移动到片段并像这样调用它:

tellJoke();

请注意,现在您没有传递this,而是传递getActivity(),因为您已经在片段中。