contextthemewrapper cannot be cast to activity

2020-02-09 00:14发布

in my small app i have a PageAdapter->Fragment->ListView->ImageView. On onImageClick i want display my image in another Fragment (Fragment3), but when i load an image in my Fragment3 get an Exception

public class Fragment3 extends DialogFragment {
ImageLoader imageLoader;
...
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    view = (ViewGroup) inflater.inflate(R.layout.fragment3_layout, container, false);
    imageView = (ImageView) view.findViewById(R.id.imageViewFrag3);
    detail = (TextView) view.findViewById(R.id.textViewFrag3);
    imageUrl = getArguments().getString("URL");
    imageView.setTag(imageUrl); 
    activity=this;      
    imageLoader = new ImageLoader(activity.getActivity().getApplicationContext());      
    imageLoader.DisplayImage(imageUrl, (Activity) activity.getActivity(), imageView);       
    return view;
}
...
}

and code which creates an Exception. When i create a fragment and add the ListView all passed ok, but when i create another fragment (child) and want to load Photo it fails.

code, how i create a child fragment, without PageAdapter

holder.imgViewImage = (ImageView) vi.findViewById(R.id.imageView01);
        holder.imgViewImage.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {                   
                android.support.v4.app.FragmentTransaction ft = activity.getFragmentManager().beginTransaction();                   
                Fragment3 newFragment = Fragment3.newInstance();                    
                Bundle bundle=new Bundle();
                bundle.putString("URL", holder.imgViewImage.getTag().toString());
                newFragment.setArguments(bundle);
                newFragment.show( ft, "dialog");
                Log.i("!!!", "Click on image");                 
            }
        })

here is Photo Loader Thread,

class PhotosLoader extends Thread {
    public void run() {
        try {
            while(true)
            {
                if(photosQueue.photosToLoad.size()==0)
                    synchronized(photosQueue.photosToLoad){
                        photosQueue.photosToLoad.wait();
                    }
                if(photosQueue.photosToLoad.size()!=0)
                {
                    PhotoToLoad photoToLoad;
                    synchronized(photosQueue.photosToLoad){
                        photoToLoad=photosQueue.photosToLoad.pop();
                    }
                    Bitmap bmp=getBitmap(photoToLoad.url);
                    cache.put(photoToLoad.url, bmp);
                    if(((String)photoToLoad.imageView.getTag()).equals(photoToLoad.url)){
                        BitmapDisplayer bd=new BitmapDisplayer(bmp, photoToLoad.imageView);            
                        //Exception contextthemewrapper cannot be cast to activity !!!
                        Activity a= (Activity)(photoToLoad.imageView.getContext());
                        a.runOnUiThread(bd);
                    }
                }
                if(Thread.interrupted())
                    break;
            }
        } catch (InterruptedException e) {
        }
    }
}

and Exception

02-09 08:22:57.510: E/AndroidRuntime(1449): FATAL EXCEPTION: Thread-114
02-09 08:22:57.510: E/AndroidRuntime(1449): java.lang.ClassCastException: android.view.ContextThemeWrapper cannot be cast to android.app.Activity
02-09 08:22:57.510: E/AndroidRuntime(1449):     at com.example.ids.ImageLoader$PhotosLoader.run(ImageLoader.java:171)

3条回答
时光不老,我们不散
2楼-- · 2020-02-09 00:55
Activity a= (Activity)(photoToLoad.imageView.getContext());

You can't assume a Context can be casted to an Activity. Hence the exception: You're attempting to cast a Context that is in fact a ContextThemeWrapper to an Activity.

You can replace

Activity a= (Activity)(photoToLoad.imageView.getContext());
a.runOnUiThread(bd);

with e.g.

photoToLoad.imageView.post(bd);

to post a Runnable to UI thread message queue, similar to Activity runOnUiThread().

查看更多
Melony?
3楼-- · 2020-02-09 01:07

From what I know, if a View that is shown in a Dialog, its context (access from view.getContext()) is actually a ThemeContextWrapper instance, which is probably not an Activity. To get the activity from the Dialog, you can use getOwnerActivity(), which returns the Activity that the Dialog belongs to.

查看更多
The star\"
4楼-- · 2020-02-09 01:12

Similar case I have. May be related question> Accessing activity from custom button

I solve my case with this snippet.

private static Activity scanForActivity(Context cont) {
    if (cont == null)
        return null;
    else if (cont instanceof Activity)
        return (Activity)cont;
    else if (cont instanceof ContextWrapper)
        return scanForActivity(((ContextWrapper)cont).getBaseContext());

    return null;
}
查看更多
登录 后发表回答