尝试在空对象引用上调用虚拟方法“android.os.Looper android.content.Context.getMainLooper()”[重复]

2024-02-21

每当我尝试在手机或模拟器上打开应用程序时,我的 Log cat 都会收到此错误。为了让您概述我当前正在做的项目,它是一个记录连接到手机上接入点的设备数据的系统,可以通过屏幕上的按钮打开和关闭这些设备。

我想归功于:

  1. Android 2.3 wifi热点API https://stackoverflow.com/questions/7048922/android-2-3-wifi-hotspot-api%3E

and

  1. https://www.whitebyte.info/android/android-wifi-hotspot-manager-class https://www.whitebyte.info/android/android-wifi-hotspot-manager-class

Log cat 文件的图像是:https://i.gyazo.com/fa068fd1fce3f27f43185c0cd12568c1.png https://i.gyazo.com/fa068fd1fce3f27f43185c0cd12568c1.png

我的主要活动课

public class MainActivity extends ActionBarActivity{

boolean wasApEnabled = false;
static AccessPoint wifiAP;
private WifiManager wifi;
static Button apButton;
static TextView textView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    apButton = (Button) findViewById(R.id.toggleBtn);
    textView = (TextView) findViewById(R.id.wifiClients);

    wifiAP = new AccessPoint();
    wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);

    scan();

    apButton.setOnClickListener(new View.OnClickListener() {
        public void onClick(View view) {
            wifiAP.toggleWifiAP(wifi, MainActivity.this);
        }
    });

    getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD|WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON|WindowManager.LayoutParams.FLAG_DIM_BEHIND);

}

private void scan(){
    wifiAP.getClientList(false, new FinishScanListener() {
        @Override
        public void onFinishScan(final ArrayList<ClientScanResult> clients) {
            textView.setText("WifiApState:" + wifiAP.getWifiApState()+ "\n\n");
            textView.append("Clients: \n");
            for (ClientScanResult clientScanResult : clients){
                textView.append("====================\n");
                textView.append("ipAddress: " + clientScanResult.getIpAddress() + "\n");
                textView.append("Device: " + clientScanResult.getDevice() + "\n");
                textView.append("macAddress: " + clientScanResult.getMacAddress() + "\n");
                textView.append("isReachable: " + clientScanResult.isReachable() + "\n");

            }
        }
    });
}

@Override
public void onResume() {
    super.onResume();
    if (wasApEnabled) {
        if (wifiAP.getWifiApState() != wifiAP.WIFI_STATE_ENABLED && wifiAP.getWifiApState() != wifiAP.WIFI_STATE_ENABLING) {
            wifiAP.toggleWifiAP(wifi, MainActivity.this);
        }
    }
    updateStatusDisplay();
}

@Override
public void onPause() {
    super.onPause();
    boolean wifiApIsOn = wifiAP.getWifiApState()==wifiAP.WIFI_STATE_ENABLED || wifiAP.getWifiApState()==wifiAP.WIFI_STATE_ENABLING;
    if (wifiApIsOn){
        wasApEnabled = true;
        wifiAP.toggleWifiAP(wifi, MainActivity.this);
    }else {
        wasApEnabled = false;
    }
    updateStatusDisplay();
}

public static void updateStatusDisplay(){
    if (wifiAP.getWifiApState()==wifiAP.WIFI_STATE_ENABLED || wifiAP.getWifiApState()==wifiAP.WIFI_STATE_ENABLING){
        apButton.setText("Turn Off");
    }else {
        apButton.setText("Turn on");
    }
}



@Override
public boolean onCreateOptionsMenu(Menu menu) {
    menu.add(0,0,0, "Get Clients");
    return super.onCreateOptionsMenu(menu);
}

public boolean onOptionsItemSelected(int featureId, MenuItem item) {
    switch (item.getItemId()){
        case 0:
            scan();
            break;
    }
    return super.onMenuItemSelected(featureId, item);
}
}

接入点类

public class AccessPoint extends Activity {
private static int constant = 0;
private Context context;

private static int WIFI_STATE_UNKNOWN = -1;
private static int WIFI_STATE_DISABLING = 0;
private static int WIFI_STATE_DISABLED = 1;
public static int WIFI_STATE_ENABLING = 2;
public static int WIFI_STATE_ENABLED = 3;
private static int WIFI_STATE_FAILED = 4;

final static String[] WIFI_STATE_TEXTSTATE = new String[]{
        "DISABLING","DISABLED","ENABLING","ENABLED","FAILED"
};

private WifiManager wifi;
private String TAG = "WifiAP";

private int stateWifi = -1;
private boolean alwaysEnabledWifi = true;


//enable or disable the wifi
public void toggleWifiAP(WifiManager wifiHandler, Context context){
    if (wifi == null){
        wifi = wifiHandler;
    }
    boolean wifiApIsOn = getWifiApState() == WIFI_STATE_ENABLED || getWifiApState()==WIFI_STATE_ENABLING;
    new SetWifiApTask(!wifiApIsOn, false, context).execute();
}

private int setWifiApEnabled(boolean enabled){
    Log.d(TAG, "Set wifi enabled called" + enabled);

    WifiConfiguration config = new WifiConfiguration();
    config.SSID = "Attend Lecture";
    config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);

    //remember wireless state
    if (enabled && stateWifi == -1){
        stateWifi = wifi.getWifiState();
    }

    //disable the wireless
    if (enabled && wifi.getConnectionInfo() !=null){
        Log.d(TAG, "disable wifi: calling");
        wifi.setWifiEnabled(false);
        int loopMax = 10;
        while (loopMax > 0 && wifi.getWifiState() != WifiManager.WIFI_STATE_DISABLED){
            Log.d(TAG, "Disable Wifi: Waiting, pass:" + (10-loopMax));
            try{
                Thread.sleep(500);
                loopMax--;
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        Log.d(TAG, "Disabling wifi is done, pass: " + (10-loopMax));
    }

    //enable and disable wifi AP
    int state = WIFI_STATE_UNKNOWN;
    try {
        Log.d(TAG, (enabled?"enabling":"Disabling")+"wifi ap: calling");
        wifi.setWifiEnabled(false);
        Method method1 = wifi.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);
        method1.invoke(wifi, config, enabled);
        Method method2 = wifi.getClass().getMethod("getWifiState");
        state = (Integer)method2.invoke(wifi);
    }catch (Exception e){
        //Log.e(WIFI_SERVICE, e.getMessage());
    }

    //Use thread while processing occurs
    if (!enabled){
        int loopMax = 10;
        while (loopMax>0 && (getWifiApState()==WIFI_STATE_DISABLING || getWifiApState()==WIFI_STATE_ENABLED || getWifiApState()==WIFI_STATE_FAILED)){
            Log.d(TAG, (enabled?"enabling": "disabling")+ "wifi AP: waiting, pass:" + (10-loopMax));
            try {
                Thread.sleep(500);
                loopMax--;
            }catch (Exception e){

            }
        }
        Log.d(TAG, (enabled?"enabling":"disabling")+" Wifi ap: done, pass: " + (10-loopMax));

        //enable the wifi
        if (stateWifi==WifiManager.WIFI_STATE_ENABLED || stateWifi==WifiManager.WIFI_STATE_ENABLING || stateWifi==WifiManager.WIFI_STATE_UNKNOWN || alwaysEnabledWifi){
            Log.d(TAG, "enable wifi: Calling");
            wifi.setWifiEnabled(true);
            //this way it doesnt hold things up and waits for it to get enabled
        }

        stateWifi = -1;
    }else if (enabled){
        int loopMax = 10;
        while (loopMax>0 && (getWifiApState()==WIFI_STATE_ENABLING || getWifiApState()==WIFI_STATE_DISABLED || getWifiApState()==WIFI_STATE_FAILED)){
            Log.d(TAG, (enabled?"Enabling": "disabling") + "wifi ap: waiting, pass: " + (10-loopMax));
            try{
                Thread.sleep(500);
                loopMax--;
            }catch (Exception e){

            }
        }
        Log.d(TAG, (enabled?"Enabling": "disabling")+ "wifi ap: done, pass: " + (10-loopMax));
    }
    return state;
}

//Get the wifi AP state
public int getWifiApState(){
    int state = WIFI_STATE_UNKNOWN;
    try {
        Method method2 = wifi.getClass().getMethod("getWifiApState");
        state = (Integer) method2.invoke(wifi);
    }catch (Exception e){

    }

    if (state>=10){
        constant=10;
    }

    WIFI_STATE_DISABLING = 0+constant;
    WIFI_STATE_DISABLED = 1+constant;
    WIFI_STATE_ENABLING = 2+constant;
    WIFI_STATE_ENABLED = 3+constant;
    WIFI_STATE_FAILED = 4+constant;

    Log.d(TAG, "getWifiApState " + (state==-1?"UNKNOWN":WIFI_STATE_TEXTSTATE[state-constant]));
    return state;
}

class SetWifiApTask extends AsyncTask<Void, Void, Void>{
    boolean mMode;
    boolean mFinish;
    ProgressDialog pDialog;

    public SetWifiApTask(boolean mode, boolean finish, Context context){
        mMode = mode;
        mFinish = finish;
        pDialog = new ProgressDialog(context);
    }

    @Override
    protected void onPreExecute(){
        super.onPreExecute();
        pDialog.setTitle("Turning on Access Point " + (mMode?"On":"Off" + "..."));
        pDialog.setMessage("Please wait a moment...");
        pDialog.show();
    }

    @Override
    protected void onPostExecute(Void aVoid){
        super.onPostExecute(aVoid);
        try {
            pDialog.dismiss();
            MainActivity.updateStatusDisplay();
        }catch (IllegalArgumentException e){

        };
        if (mFinish){
            finish();
        }
    }

    @Override
    protected Void doInBackground(Void... params) {
        setWifiApEnabled(mMode);
        return null;
    }
}

//get the list connected to the wifi hotspot
public void getClientList(boolean onlyReachable, FinishScanListener finishListener){
    getClientList(onlyReachable, 300, finishListener);
}

public void getClientList(final boolean onlyReachable, final int reachableTimeout, final FinishScanListener finishListener){

    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            BufferedReader br = null;
            final ArrayList<ClientScanResult> result = new ArrayList<>();

            try {
                br = new BufferedReader(new FileReader("/proc/net/arp"));
                String line;
                while ((line = br.readLine()) != null){
                    String[] splitted = line.split(" +");

                    if ((splitted !=null) && (splitted.length >=4)){
                        String mac = splitted[3];

                        if (mac.matches("..:..:..:..:..:..")){
                            boolean isReachable = InetAddress.getByName(splitted[0]).isReachable(reachableTimeout);

                            if (!onlyReachable || isReachable){
                                result.add(new ClientScanResult(splitted[0], splitted[3], splitted[5], isReachable));
                            }
                        }
                    }
                }
            }catch (Exception e){
                Log.e(this.getClass().toString(), e.toString());
            }finally {
                try {
                    br.close();
                }catch (IOException e){
                    Log.e(this.getClass().toString(), e.getMessage());
                }
            }
            //Get handler that will be used to post to main thread
            Handler mainHandler = new Handler(context.getMainLooper());
            Runnable myRunnable = new Runnable() {
                @Override
                public void run() {
                    finishListener.onFinishScan(result);
                }
            };
            mainHandler.post(myRunnable);
        }
    };

    Thread myThread = new Thread(runnable);
    myThread.start();

}


}

据我所知,你的Context is null。你有一个私有变量Context在你的班级中名列前茅,但你从来没有给它分配任何东西,所以它是null.

给你的AccessPoint一个构造函数并放置类似的东西

context = getContext();

在它里面。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

尝试在空对象引用上调用虚拟方法“android.os.Looper android.content.Context.getMainLooper()”[重复] 的相关文章

随机推荐

  • OSGI环境中单例的迁移解决方案

    我正在 Java EE 环境中工作 其中每个应用程序都位于其自己的 war 文件中 在每个应用程序 war 文件的 WEB INF lib 中 有一个由所有应用程序共享的公共 jar 这个公共 jar 包含几个可以从代码中的许多点访问的单例
  • 从 HashMap 获取值时为什么需要双 & 符号?

    我在 Rust 中的引用方面遇到了一些麻烦 我有以下无法编译的代码 use std collections HashMap fn main let mut map HashMap new map insert 0 0 map insert
  • 按发布降序显示帖子

    我正在尝试测试 Firebase 以允许用户使用以下方式发表评论push 我想用以下内容显示我检索到的数据 fbl child sell limit 20 on value function fbdata handle data displ
  • 当向 RecyclerView ListAdapter 提交新列表时,差异检查始终为 areContentsTheSame() 返回 true

    我正在使用 MVVM 架构来构建一个简单的订购应用程序 我在 ProductsFragment 中使用 RecyclerView 来列出所有可以订购的产品 我还在我的 ViewModel 中使用 LiveData 并在我的 Fragment
  • 满足我需求的强制门户

    我正在为我的组织寻找强制门户 我看到很多这样的应用程序将允许用户在 a 输入凭据或 b 付款后通过 我正在寻找的东西有点不同 让我介绍一些有关我的系统的基础知识 我正在使用活动目录和内部 DNS 运行基于 Windows 的网络 我有一个内
  • jquery Flexslider 手动控件不起作用

    我正在尝试为 flexslider 插件实现手动控制 这是我的代码 div class container div class columns row div class flexslider ul class slides li styl
  • 从 Flask-sqlalchemy 中的连接查询读取

    成功连接两个数据库表后 我尝试通过寻址第一个表来读取第二个表中的数据 我正在致辞opinion topic name来自我的 jinja2 模板 但没有返回任何内容 如何从连接的查询中访问 Topic topic name 值 view m
  • 内联图像未从 GatsbyJS 中的 markdown 文件正文加载

    我正在尝试使用 gatsby remark images 在我的 markdown 文件中使用内联图像 不幸的是 该图像无法加载到我的本地主机上 我不知道这是否只是语法错误 或者我错过了一些重大的东西 这是config https gith
  • __iter__ 是如何工作的?

    尽管阅读了它 但我仍然不太明白如何 iter 作品 一个简单的解释是什么 我见过def iter self return self 我不知道这是如何工作的 也不知道这是如何工作的步骤 我可以简单地说 iter 在类上定义一个方法 该方法将返
  • JXTable 列排序在 1.0 和 1.6 之间发生变化

    自从我们更新到 JDK1 6 以来 我最近将应用程序中的 SwingX 库从版本 1 0 更新到了 1 6 2 我知道排序已更改为重新使用 JDK 1 6 中引入的一些核心 JDK 组件 但是 在版本 1 0 中 可以通过单击标题对列进行排
  • 为什么相同时间的 Unix 时间戳在不同时区不同

    Why 7 18 2013 11 33GMT 时区和我当地的时区 亚洲 加尔各答 是否不同 由于 Unix 时间戳是自纪元时间以来计算的刻度1 1 1970 00 00 00 GMT所以我知道纪元时间在不同时区的不同间隔发生 但仍然如此 经
  • 在 C++ 11 中创建动态二维矩阵的好方法

    我已经知道如何使用创建动态二维矩阵new并使用释放它delete 由于 C 11 具有许多新的内存功能 例如unique ptr array容器等 创建 2D 矩阵的一种好方法是什么 这样就不需要显式地使用释放矩阵delete操作员 最简单
  • Laravel 5 不从点 ENV 文件读取值

    我不知道这个问题是否相关 LARAVEL 5 仍处于开发阶段 在观看了有关 LARAVEL 5 新功能的 Laracast 视频之一后 我已经拉取了 LARAVEL 5 我迫不及待地等待它的正式发布 我命名了本地环境dot文件为 env l
  • 如果我在一个类中有多个测试并且前面的测试失败,我如何让它跳过或退出该类而不是测试其余的测试?

    我将 Python 与 Selenium 和 unittest 结合使用 我在一堂课中有四个测试 因为它们都是相关的单元测试 如果前面的测试失败 如何让它跳过下一个测试 我已经阅读了unittest的skip方法的所有文档 但没有一个正是我
  • 显示事件的典型 uml 图

    我有几个模块 他们通过事件相互交流 通常使用什么 UML 图来显示这一点 人们使用非 uml 图吗 有什么例子吗 我想你肯定想要一个顺序图 http en wikipedia org wiki Sequence diagram按顺序显示模块
  • Laravel Eloquent 截断数据类型 double

    Laravel 截断 double 类型的值 值 3 539363636363637 显示为3 5393636363636 我这样做 e Enrollment find 173 dd e gt value show 3 5393636363
  • Docker swarm:如何手动设置节点名称?

    有关我的环境的一些背景 我有 docker swarm 在 3 个 ubuntu 14 04 vagrant 盒子上运行 swarm master 在一台机器上运行 带有 consul 另外 2 台机器正在运行加入到 master 的 Sw
  • C# 数组列表的排列?

    我有一个 ArrayList myList 我正在尝试创建数组中值的所有排列的列表 示例 所有值都是字符串 myList 0 1 5 3 9 myList 1 2 3 myList 2 93 myList 的计数可以变化 因此它的长度事先未
  • 如何将Transaction对象转换为R中的Dataframe

    如何将 arules 包中的数据集 Groceries 转换为数据帧 class Groceries 1 transactions attr package 1 arules 您需要指定实际需要的内容 我没有看到as data frame
  • 尝试在空对象引用上调用虚拟方法“android.os.Looper android.content.Context.getMainLooper()”[重复]

    这个问题在这里已经有答案了 每当我尝试在手机或模拟器上打开应用程序时 我的 Log cat 都会收到此错误 为了让您概述我当前正在做的项目 它是一个记录连接到手机上接入点的设备数据的系统 可以通过屏幕上的按钮打开和关闭这些设备 我想归功于