androidloaderunchecked-cast

How to solve Unchecked cast in android without suppressing the warning


How do I solve this issue without using SuppressWarning("uncheckedcast"), this there any way to check the object before casting it or any other way to solve this issue. The problem is inside onLoadFinished(). I am using the data for different datatypes as you can see, first as boolean and then List. Thank you in advance.

 package com.howaboutthis.satyaraj.wallpaper;

import android.support.v4.app.Fragment;
import android.support.v4.content.Loader;
import android.content.Context;
import android.content.DialogInterface;    
import android.support.v4.app.LoaderManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.util.ArrayList;

import java.util.List;
import java.util.Objects;


public class FragmentChanging extends Fragment implements LoaderManager.LoaderCallbacks  {

    private ProgressDialog dialog;

    public FragmentChanging(){
    }

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

    }

    @Override
    public View onCreateView(final LayoutInflater inflater, ViewGroup
    container,
                             Bundle savedInstanceState) {

        final View view = 
   inflater.inflate(R.layout.fragment_changing_wallpaper, container, false);

     getLoaderMangaer.init(0,null,FragmentChanging.this);

        return view;
    }

    @Override
    public Loader onCreateLoader(int id, Bundle args) {
        if (id == 0 || id == 2){
            dialog.setMessage("Loading Settings...");
            dialog.show();
              }
            return new TestInternetLoader(getContext());           
              }

        return null;
    }


    @Override
    public void onLoadFinished(Loader loader, Object data) {
        int id = loader.getId();

        if (id == 0 || id == 2){
            boolean check = (Boolean) data;
            if (check) 
                if (dialog.isShowing()) dialog.dismiss();
        }
        else if(id == 3)
            List<Bitmap> bitmaps = (List<Bitmap>) data;  //Unchecked cast

    }

    @Override
    public void onLoaderReset(Loader loader) {

    }

}  

Solution

  • You can get rid of the lint warning by using a LoaderManager.LoaderCallbacks<List<Bitmap>> . If you want to do so, you'll have to change (almost) every occurrence of Loader to Loader<List<Bitmap>>. (An exception seems to be onLoaderReset(Loader loader))

    Moreover, if you use a custom AsyncTaskLoader it would have to extend AsyncTaskLoader<List<Bitmap>>.

    Then you can write

    @Override
    public void onLoadFinished(Loader<List<Bitmap>> loader, List<Bitmap> data) {
    
        List<Bitmap> bitmaps = data;
    }
    

    EDIT

    If the suggested approach is not possible because the type of data may vary you can check for the types you are going to handle like this:

    if (data instanceof List<?>){
        List temp = (List)data;
        // do what's required for List data
        // (if necessary do a type check on list elements)
        if (tempList.size() > 0){
            Object firstItem = tempList.get(0);
            if (firstItem instanceof Bitmap){
                // now you know that your Loader gave you a List with at least one Bitmap
                List<Bitmap> bitmaps = new ArrayList<>();
                for (Object item: tempList){
                    if (item instanceof Bitmap){
                        bitmaps.add((Bitmap) item);
                    }
                }
            }
        }
    }
    else if (data instanceof Boolean){
       boolean check = (Boolean) data;
            if (check){ 
                // handle Boolean data   
            } 
    }