【问题标题】:contextthemewrapper cannot be cast to activitycontextthemewrapper 不能被强制转换为活动
【发布时间】:2014-03-06 14:15:37
【问题描述】:

在我的小应用程序中,我有一个 PageAdapter->Fragment->ListView->ImageView。在 onImageClick 上,我想在另一个 Fragment (Fragment3) 中显示我的图像,但是当我在 Fragment3 中加载图像时出现异常

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

以及创建异常的代码。当我创建一个片段并添加 ListView 时一切正常,但是当我创建另一个片段(子)并想要加载照片时它失败了。

代码,我如何在没有 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");                 
            }
        })

这里是 Photo Loader 线程,

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

和例外

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)

【问题讨论】:

  • 这段代码在哪里 Activity a=(Activity)photoToLoad.imageView.getContext(); ?

标签: android fragment


【解决方案1】:

我有类似的情况。 可能是相关问题>Accessing activity from custom button

我用这个 sn-p 解决了我的问题。

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

【讨论】:

    【解决方案2】:
    Activity a= (Activity)(photoToLoad.imageView.getContext());
    

    您不能假设 Context 可以转换为 Activity。因此例外情况:您尝试将实际上是 ContextThemeWrapperContext 转换为 Activity

    你可以替换

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

    例如

    photoToLoad.imageView.post(bd);
    

    向 UI 线程消息队列发布 Runnable,类似于 Activity runOnUiThread()

    【讨论】:

      【解决方案3】:

      据我所知,如果在 Dialog 中显示一个 View,它的上下文(从 view.getContext() 访问)实际上是一个 ThemeContextWrapper 实例,它可能不是一个 Activity。要从Dialog中获取Activity,可以使用getOwnerActivity(),返回Dialog所属的Activity。

      【讨论】:

        【解决方案4】:

        kikea's 答案之外的 Kotlin 解决方案。

        fun Context.scanForActivity(): AppCompatActivity? {
           return when (this) {
               is AppCompatActivity -> this
               is ContextWrapper -> baseContext.scanForActivity()
               else -> null
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-05-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多