绑定service报错: java.lang.ClassCastException: android.os.BinderProxy cannot be cast to com.lubo.fmdigit

本文分析了在Android应用中使用远程Service和本地Service时出现的类型转换错误问题。通过理解Application的onCreate方法执行机制及跨进程绑定原理,提供了一个实用的解决方案,即使用AppProcessUtil类来判断当前是否为主进程,从而避免类型转换错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原因:使用了远程service和本地service,并且在## 标题 application中使用了bindservice绑定本地service。本质就是application的oncreate方法执行了2次,第二次是在远程进程中执行,在远程进程中执行到bindservice时,变成了跨进程绑定,应该使用binder的代理,因此类型转换错误。
解决办法:

   package com.lubo.fmdigital.m3u8play;

import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.app.ActivityManager.RunningServiceInfo;
import android.app.ActivityManager.RunningTaskInfo;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManager;
import android.util.Log;

import java.util.Iterator;
import java.util.List;

/**
 * 线程、进程 app工具类
 * Created by chandlerbing on 2017/2/22.
 */

public class AppProcessUtil {

    /**
     * 获取运行的进程id
     * @return
     */
    public static int getProcessId() {

        return android.os.Process.myPid();
    }


    /**
     * 根据进程id获取进程名
     * @param context
     * @param pID
     * @return
     */
    public static String getProcessName(Context context, int pID) {
        if(context == null) {
            return null;
        }
        String processName = null;
        Context appContext = context.getApplicationContext();
        ActivityManager am = (ActivityManager) appContext.getSystemService(Context.ACTIVITY_SERVICE);
        List l = am.getRunningAppProcesses();
        Iterator i = l.iterator();
        PackageManager pm = appContext.getPackageManager();
        while (i.hasNext()) {
            RunningAppProcessInfo info = (RunningAppProcessInfo) (i.next());
            try {
                if (info.pid == pID) {

                    processName = info.processName;
                    return processName;
                }
            } catch (Exception e) {
                // Log.d("Process", "Error>> :"+ e.toString());
            }
        }
        return processName;
    }

    /**
     * 获取运行该方法的进程的进程名
     * @param context
     * @return
     */
    public static String getProcessName(Context context) {
        if(context == null) {
            return null;
        }
        int pID = getProcessId();
        String processName = null;
        Context appContext = context.getApplicationContext();
        ActivityManager am = (ActivityManager) appContext.getSystemService(Context.ACTIVITY_SERVICE);
        List l = am.getRunningAppProcesses();
        Iterator i = l.iterator();
        PackageManager pm = appContext.getPackageManager();
        while (i.hasNext()) {
            RunningAppProcessInfo info = (RunningAppProcessInfo) (i.next());
            try {
                if (info.pid == pID) {

                    processName = info.processName;
                    return processName;
                }
            } catch (Exception e) {
                // Log.d("Process", "Error>> :"+ e.toString());
            }
        }
        return processName;
    }

    /**
     * 判断该进程是app进程还是远程service进程
     * @param c
     * @return
     */
    public static boolean isAppProcess(Context c) {
        if(c == null) {
            return false;
        }
        c = c.getApplicationContext();

        String processName = getProcessName(c);
        if (processName == null || !processName.equalsIgnoreCase(c.getPackageName())) {
            return false;
        }else {
            return true;
        }
    }


    /**
     * app是否在前台运行  后台运行指的是只有所属的service运行
     * 需要权限:android.permission.GET_TASKS
     * @param context
     * @return
     */
    public static boolean isAppRunningForeground(Context context) {
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);

        List<RunningTaskInfo> tasks = am.getRunningTasks(1);
        if(tasks != null && !tasks.isEmpty()) {
            ComponentName topActivity = tasks.get(0).topActivity;
            if(!topActivity.getPackageName().equalsIgnoreCase(context.getPackageName())) {
                return false;
            }else {
                return true;
            }
        }
        return false;

    }


    /**
     * 判断服务是否运行
     * @param context
     * @param serviceName
     * @return
     */
    public static boolean isServiceRunning(Context context, String serviceName) {

        boolean isRunning = false;
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<RunningServiceInfo> lists = am.getRunningServices(100);

        for (RunningServiceInfo info : lists) {//判断服务
            if(info.service.getClassName().equals(serviceName)){
                Log.i("Service1进程", ""+info.service.getClassName());
                isRunning = true;
            }
        }


        return isRunning;
    }


    /**
     * 判断进程是否在运行
     * @param context
     * @param proessName
     * @return
     */
    public static boolean isProessRunning(Context context, String proessName) {

        boolean isRunning = false;
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);

        List<RunningAppProcessInfo> lists = am.getRunningAppProcesses();
        for(RunningAppProcessInfo info : lists){
            if(info.processName.equals(proessName)){
                //Log.i("Service2进程", ""+info.processName);
                isRunning = true;
            }
        }

        return isRunning;
    }


}

使用isAppProcess(context)判断是主线程,在主线程进行绑定service即可。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值