Java 将活动上下文强制转换到接口会引发ClassCastException

Java 将活动上下文强制转换到接口会引发ClassCastException,java,android,classcastexception,Java,Android,Classcastexception,我制作了一个类LocationFinder,用于获取用户的位置 我正在实例化类和类,并调用所需的方法来获取位置 现在,在LocationFinder类中找到位置后,我想与我的MainActivity通信,以便在某些文本视图上更新用户的位置 为此,我做了以下工作: myLocationFinder类的构造函数如下所示: private Context context; private OnLocationFoundListener onLocationFoundListener; public

我制作了一个类
LocationFinder
,用于获取用户的位置

我正在实例化类和类,并调用所需的方法来获取位置

现在,在
LocationFinder
类中找到位置后,我想与我的
MainActivity
通信,以便在某些文本视图上更新用户的位置

为此,我做了以下工作:

my
LocationFinder
类的构造函数如下所示:

private Context context;
private OnLocationFoundListener onLocationFoundListener;

public LocationFinder(Context context) {
    this.context = context;
    onLocationFoundListener = (OnLocationFoundListener) context; // here is the exception is thrown
}
其中,
OnLocationFoundListener
是一个类似于:

public interface OnLocationFoundListener
{
    void setOnLocationFoundListener(String cityName, String stateName, String countryName);
}
在成功找到位置后,我使用的是
onLocationFoundListener.setOnLocationFoundListener(cityName、stateName、countryName)
通知
main活动
,我正在执行
OnLocationFoundListener
并重写所需的方法

代码示例为:

LocationFinder
类:

public class LocationFinder implements LocationListener {

    private Context context;
    private OnLocationFoundListener onLocationFoundListener;

    public LocationFinder(Context context) {
        this.context = context;
        onLocationFoundListener = (OnLocationFoundListener) context;
    }

    private static final int MY_PERMISSIONS_ACCESS_FINE_LOCATION = 1;

    private LocationManager locationManager;
    private ProgressDialog progressDialog;


    void getCityByLocation() {
        locationManager = (LocationManager) context.getSystemService(LOCATION_SERVICE);

        if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            if (ActivityCompat.shouldShowRequestPermissionRationale((Activity)context,
                    Manifest.permission.ACCESS_FINE_LOCATION)) {
                // Explanation not needed, since user requests this himself

            } else {
                ActivityCompat.requestPermissions((Activity)context,
                        new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                        MY_PERMISSIONS_ACCESS_FINE_LOCATION);
            }

        } else if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER) ||
                locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
            progressDialog = new ProgressDialog(context);
            progressDialog.setMessage(context.getString(R.string.getting_location));
            progressDialog.setCancelable(false);
            progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, context.getString(R.string.dialog_cancel), new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    try {
                        locationManager.removeUpdates(LocationFinder.this);
                    } catch (SecurityException e) {
                        e.printStackTrace();
                    }
                }
            });
            progressDialog.show();
            if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
                locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);
            }
            if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
                locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
            }
        } else {
            showLocationSettingsDialog();
        }
    }




    @Override
    public void onLocationChanged(Location location) {

        progressDialog.hide();
        try {
            locationManager.removeUpdates(this);
        } catch (SecurityException e) {
            Log.e("LocationManager", "Error while trying to stop listening for location updates. This is probably a permissions issue", e);
        }
        Log.i("LOCATION (" + location.getProvider().toUpperCase() + ")", location.getLatitude() + ", " + location.getLongitude());
        double latitude = location.getLatitude();
        double longitude = location.getLongitude();
        getCityDetails(latitude, longitude);

    }

    @Override
    public void onStatusChanged(String s, int i, Bundle bundle) {

    }

    @Override
    public void onProviderEnabled(String s) {

    }

    @Override
    public void onProviderDisabled(String s) {

    }

    private void getCityDetails(double lat, double lon)
    {
        Geocoder geocoder = new Geocoder(context, Locale.getDefault());
        List<Address> addresses = null;
        try {
            addresses = geocoder.getFromLocation(lat, lon, 1);
        } catch (IOException e) {
            e.printStackTrace();
        }
        String cityName = addresses.get(0).getAddressLine(0);
        String stateName = addresses.get(0).getAddressLine(1);
        String countryName = addresses.get(0).getAddressLine(2);

        progressDialog.dismiss();
        onLocationFoundListener.setOnLocationFoundListener(cityName, stateName, countryName);

    }

    private void showLocationSettingsDialog() {
        AlertDialog.Builder alertDialog = new AlertDialog.Builder(context);
        alertDialog.setTitle(R.string.location_settings);
        alertDialog.setMessage(R.string.location_settings_message);
        alertDialog.setPositiveButton(R.string.location_settings_button, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                context.startActivity(intent);
            }
        });
        alertDialog.setNegativeButton(R.string.dialog_cancel, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                dialog.cancel();
            }
        });
        alertDialog.show();
    }

    public interface OnLocationFoundListener
    {
        void setOnLocationFoundListener(String cityName, String stateName, String countryName);
    }
}
日志:

ComponentInfo{com.amitupadhyay.citybasedlocation/com.amitupadhyay.citybasedlocation.MainActivity}: java.lang.ClassCastException:android.app.Application无法强制转换 到 com.amitupadhayay.citybasedlocation.LocationFinder$OnLocationFoundListener 在 android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2456) 在 android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2523) 在android.app.ActivityThread.access$900(ActivityThread.java:168) 在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:1373) 位于android.os.Handler.dispatchMessage(Handler.java:102) 位于android.os.Looper.loop(Looper.java:148) 位于android.app.ActivityThread.main(ActivityThread.java:5609) 位于java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797) 位于com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687) 原因:java.lang.ClassCastException:android.app.Application 不能投靠 com.amitupadhayay.citybasedlocation.LocationFinder$OnLocationFoundListener 在 com.amitupadhayay.citybasedlocation.LocationFinder.(LocationFinder.java:38) 在 com.amitupadhyay.citybasedlocation.MainActivity.onCreate(MainActivity.java:21) 位于android.app.Activity.performCreate(Activity.java:6307) 在 android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118) 在 android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2409) 在 android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2523) 在android.app.ActivityThread.access$900(ActivityThread.java:168) 在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:1373) 位于android.os.Handler.dispatchMessage(Handler.java:102) 位于android.os.Looper.loop(Looper.java:148) 位于android.app.ActivityThread.main(ActivityThread.java:5609) 位于java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797) 位于com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687)


我不明白为什么会发生这种情况?

尝试将其作为上下文而不是应用程序上下文传递

 LocationFinder locationFinder = new LocationFinder(this);
            locationFinder.getCityByLocation();

编辑这正是日志猫所说的。您正在尝试将应用程序上下文传递给活动。

您应该使用
OnLocationFoundListener
更改构造函数中的
OnLocationFoundListener
上下文参数

public LocationFinder(OnLocationFoundListener context) {
    this.context = context;
    onLocationFoundListener =  context; // here is the exception is thrown
}
你应该通过

MainActvity.this.



 LocationFinder locationFinder = new LocationFinder(MainActvity.this);

像下面这样改变它

public LocationFinder(Context context, OnLocationFoundListener listener) {
        this.context = context;
        onLocationFoundListener = listener;
}
从活动开始,像这样开始

LocationFinder locationFinder = new LocationFinder(getApplicationContext(), this);

添加异常pleasepost logcat Please必须使用活动上下文,而不是ap
public LocationFinder(Context context, OnLocationFoundListener listener) {
        this.context = context;
        onLocationFoundListener = listener;
}
LocationFinder locationFinder = new LocationFinder(getApplicationContext(), this);