代码在单独的线程

时间:2016-07-01 08:38:31

标签: java android multithreading android-runonuithread

背景

这个应用程序是一个简单的Wifi管理器,收集/扫描并在列表视图中显示结果。由于此扫描按间隔扫描,因此我创建了一个线程并在扫描之间设置了Thread.sleep(间隔),因此在处理完成后,它会休眠X毫秒。

我已对代码进行了一些更改" /更新,现在我的应用程序进入ANR状态并显示调试器消息"Signal Catcher"]: reacting to signal 3

完整错误:

07-01 10:14:16.772 10027-10034/com.cynetstudios.wifimanager I/art: Thread[2,tid=10034,WaitingInMainSignalCatcherLoop,Thread*=0xa9007000,peer=0x12d1a0a0,"Signal Catcher"]: reacting to signal 3
07-01 10:14:17.101 10027-10034/com.cynetstudios.wifimanager I/art: Wrote stack traces to '/data/anr/traces.txt'

问题:

在添加权限之前:

在main的onCreate()中,我使用了我的代码来启动扫描循环并开始输出数据,这工作正在按预期输出数据。

线程代码:

    t = new Thread(new Runnable() {
        public void run() {
            while (!bStopThread) {
                ThreadCounter++;

                if (bSafe) {
                    initWiFiArrays(); //Scans and inserts data into lists
                    CreateSetAdapter(); //Converts lists into adapter, and sets adapter to ExpandableListView
                    threadRefresh.setText("# Refreshed Times : " + String.valueOf(ThreadCounter));
                    writeResultsToFile(); //Write results to file
                } else
                    stopScan();

                try {
                    Thread.sleep(scanInterval);
                } catch (Exception x) {
                    x.printStackTrace();
                }
            }
        }
    });
    t.start();

添加权限后

在做了一些研究之后,我发现我应该从onCreate中删除这个Initiate scan方法,因为它会阻止任何线程调用,我将它添加到onStart并添加了一个只访问UI的方法RunOnUITHD(Runnable r)用基本代码更新。

新主题代码:

     t = new Thread(new Runnable() {
        public void run() {
            while (!bStopThread) {
                ThreadCounter++;

                if (bSafe) {
                    initWiFiArrays();
                    CreateSetAdapter();
                    RunOnUITHD(new Runnable() {
                        @Override
                        public void run() {
                            threadRefresh.setText("# Refreshed Times : " + String.valueOf(ThreadCounter));
                        }
                    });
                    writeResultsToFile();
                } else
                    stopScan();

                try {
                    Thread.sleep(scanInterval);
                } catch (Exception x) {
                    x.printStackTrace();
                }
            }
        }
    });
    t.start();

处理程序的定义是:handler = new Handler(context.getMainLooper());

RunOnUITHD

private void RunOnUITHD(Runnable runnable) {
    handler.post(runnable);
}

我仍在接受ANR(latest ANR Traces)并且我不在乎,我不知道我做错了什么。

更新

我记录了主线程代码的每一部分,它按预期运行,循环和休眠,但UI没有更新...

将记录代码添加到new Runnable()我注意到以下内容:

向ThreadCounter添加一个断点,例如ThreadCounter==11应该导致10"更新线程......"和"完成更新......"循环,如下面的代码所示。

RunOnUITHD(new Runnable() {
    @Override
    public void run() {
        logm("POST HANDLER: updating Thread Refresh Text");
        threadRefresh.setText("# Refreshed Times : " + String.valueOf(ThreadCounter));
        logm("POST HANDLER: Finished update Thread Refresh Text");
    }
});

相反,我只注意到日志中显示的4个循环。

运行进一步的测试,ThreadCounter==3,循环记录= 1,所有进一步的测试都会导致1个记录的更新setText循环。

由于此线程是通过checkPermissions()@Override onStart()的自定义方法启动的,因此我会显示一个toast消息,然后是checkPermissions

@Override
protected void onStart() {
    super.onStart();
    Toast.makeText(main.this, "Starting Service", Toast.LENGTH_SHORT).show();
    logm("checking permissions in 'onStart'");
    checkPermissions();
}

通过这些测试,Toast Message显示(不会消失)并且setText在1循环上更新,这意味着threadRefresh TextView包含以下文本:&#34; #Rereshed Times:1&#34; < / p>

1 个答案:

答案 0 :(得分:1)

原来我没有死锁,这是由于Intents选择不当。

<强>原因:

我使用的是Intent。这创建了一个创建PendingIntent的服务(用于点击通知以重新打开应用程序),这锁定了我的UI线程。因此,我上面的代码中没有任何内容影响/导致问题!

我是如何解决的:

使用日志。不是自定义日志,只是简单的Log.i()

我记录了我的代码的每一部分:

  1. 从高层开始,并找到可能的原因。

  2. 如果这不起作用/产生结果,看看你是否有其他类,在我的例子中是一个ServiceClass,记录它。

  3. 这是我发现我的代码没有进一步执行的地方,所以回溯到调用代码,我发现我使用了一个等待意图完成的Intent,然后继续前进,从而导致我的代码挂起。

    <强>解决方案:

    应该使用的是用于服务的两种意图类型之一。

    这些是经常被询问和记录良好的对象。关于这两种意图类型之间的差异,StackOverflow有很多问题,herehere是2个排名很高的问题,还有一点UI and service Question

    我将使用IntentService。

    希望这有帮助!