【问题标题】:Android service with handler and thread带有处理程序和线程的 Android 服务
【发布时间】:2014-01-19 13:08:03
【问题描述】:

我有一个启动新服务的应用程序。在这个服务中,我目前有一个处理程序,它每分钟做一些工作,然后通过广播接收器将结果发送到主活动。我想要以下内容:每分钟在服务中创建一个新线程,使其完成工作并向处理程序发送一条消息,说明它已完成,然后处理程序将通过广播接收器发送到主活动。我如何结合线程和处理程序?这是我到目前为止所拥有的 - 只是感兴趣的代码的一部分 -

private Runnable sendUpdatesToUI = new Runnable() {



    public void run() {
        try {
            getAppResources(); //this is the work i want to place in a new thread
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        intent.putExtra(key,value);
        sendBroadcast(intent);
        handler.postDelayed(this, 60*1000); 
    }
};

这是我知道我需要做的事情

 private Runnable sendUpdatesToUI = new Runnable() {

    public void run() {
       /* try {
            getAppResources();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }*/

         Thread t = new Thread() {
            @Override
            public void run(){
                 try {
                    getAppResources();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
               handler.sendEmptyMessage(0);
            }
        };


        handler.postDelayed(this, 60*1000); 
    }
};

我在哪里放置 handleMessage ?如果我将它放在 Runnable 中,它会说它永远不会在本地使用。我只是把它放在 Runnable 之前?

 public void handleMessage(Message msg){
    if(msg.what == 0){
        intent.putExtra(key,value);
        sendBroadcast(intent);
    }
 }

我应该这样做吗?

编辑:向主要活动发送一些数据的处理程序代码

 private final Handler handler = new Handler(){
     public void handleMessage(Message msg){
        if(msg.what == 0){
             Log.d("HANDLE","Am primit mesaj");
            //Notify preparations
            intent.putExtra("RunningApps", runningApps.size());
            intent.putExtra("CPU", highestDrainPackageCPU);

            intent.putExtra("GPS",highestDrainPackageGPS);
            intent.putExtra("WIFI", highestDrainPackageWIFI);

            //Now i have all my data, time to send them to the activity
            //First , send the strings to be set in the TextViews
            //Each running app has 7 messages to display -> ArrayList<String>
            for(int i=0;i<runningApps.size();i++){
                intent.putStringArrayListExtra(String.valueOf(i), appInfo.get(i));
            }

            //Next send values to plot the chart
            //CPU energy consumption for highest draining application
            double [] currValues_cpu = new double[tableCPU.get(highestDrainPackageCPU).size()];
            Log.d("CPUSIZE",String.valueOf(currValues_cpu.length));
            for(int j=0;j<tableCPU.get(highestDrainPackageCPU).size();j++){
                currValues_cpu[j]=tableCPU.get(highestDrainPackageCPU).get(j);
                Log.d("CPUVALUE",String.valueOf(currValues_cpu[j])+"For application"+highestDrainPackageCPU);
            }

            intent.putExtra("highestDrainPackageCPU", currValues_cpu);


            //GPS energy consumption for highest draining application
            double [] currValues_gps = new double[tableGPS.get(highestDrainPackageGPS).size()];
            for(int j=0;j<tableGPS.get(highestDrainPackageGPS).size();j++){
                currValues_gps[j]=tableGPS.get(highestDrainPackageGPS).get(j);
            }
            intent.putExtra("highestDrainPackageGPS", currValues_gps);

            //WIFI energy consumption for highest draining application
            double [] currValues_wifi = new double[tableWIFI.get(highestDrainPackageWIFI).size()];
            for(int j=0;j<tableWIFI.get(highestDrainPackageWIFI).size();j++){
                currValues_wifi[j]=tableWIFI.get(highestDrainPackageWIFI).get(j);
            }
            intent.putExtra("highestDrainPackageWIFI", currValues_wifi);

            sendBroadcast(intent);

        }
    }
};

这里是 Main Activity 中的 BroadcastReceiver 和 UpdateUI 函数:

 private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        updateUI(intent);       
    }
};

public void updateUI(Intent intent){

    resourceTab.removeAllViews();
    //statisticsTab.removeAllViews();

    int apps_no = intent.getIntExtra("RunningApps", 0);

    String highestDrainPackageCPU = intent.getStringExtra("CPU");

    String highestDrainPackageGPS = intent.getStringExtra("GPS");

    String highestDrainPackageWIFI = intent.getStringExtra("WIFI");


    //TO-DO: Get information for each app and store it in textview.Then add it to a linearlayout
    for(int i=0;i<apps_no;i++){

        //Setup delimiter
        View delimitator = new View(this);
        delimitator.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,1));
        delimitator.setBackgroundColor(Color.parseColor("#50FFFFFF"));

        //Extract values
        ArrayList<String> info = new ArrayList<String>();
        info=intent.getStringArrayListExtra(String.valueOf(i));

        for(int j=0;j<info.size();j++){
            TextView infoApp = new TextView(this);
            //////Setup textview//////////
            infoApp = new TextView(this);
            infoApp.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT));
            infoApp.setTextColor(Color.parseColor("#FFFFFF"));
            infoApp.setText(info.get(j));

            resourceTab.addView(infoApp);
        }

        //Add delimiter
        resourceTab.addView(delimitator);
    }

    double [] cpu_values = intent.getDoubleArrayExtra("highestDrainPackageCPU");

    double [] gps_values = intent.getDoubleArrayExtra("highestDrainPackageGPS");

    double [] wifi_values = intent.getDoubleArrayExtra("highestDrainPackageWIFI");

    //Now plot the graph
    createGraphOverall(cpu_values, gps_values, wifi_values, highestDrainPackageCPU, highestDrainPackageGPS, highestDrainPackageWIFI);

    //Update the table
    updateTable(cpu_values, gps_values, wifi_values, highestDrainPackageCPU, highestDrainPackageGPS, highestDrainPackageWIFI);

}

在我尝试创建一个新线程来完成服务内的繁重工作之前,我的 Activity 已成功更新。

【问题讨论】:

    标签: android multithreading android-service


    【解决方案1】:

    编辑:抱歉,我想我之前注意到了,并被处理程序跟踪。

    您创建了线程 t,但您从未运行它。

    t.start();
    

    您将 handleMessage() 定义为处理程序的方法,如下所示:

    handler = new Handler() {
    
        @Override
        public void handleMessage(Message msg) {
    
            //TODO: Handle different types of messages
    
       }
    };
    

    【讨论】:

    • 感谢您的快速响应。我确实做到了,但似乎我没有收到广播,或者至少不是我的主要活动中的所有广播。有什么理由吗?
    • 处理程序不会接收广播,如果这是您的想法。如果你有一个 BroadcastReceiver 可能会发布如何定义的代码。
    • 我不希望它接收。实际上,我的处理程序将广播发送到我的主要活动。我只希望我的处理程序知道何时从新创建的线程收集数据。我在服务中有一些保存数据的全局变量。我在新线程中收集数据,然后在处理程序中访问它。还是我做不到?我将用代码编辑帖子
    • 因此,您不会收到所有广播。你得到一些吗?我会将 Log.d() 语句放在你的 thread.run()、handleMessage() 和 BroadcastReceiver 中,以确定发生通信故障的位置。
    • 不,我尝试放置一些消息,但我没有收到任何广播。在handleMessage 中,一切似乎都很好,只有在我的onReceive() 活动中我什么也没得到。编辑:当我尝试从 Hashtable tableCPU 获取数据时,我似乎在 handleMessage 中得到了 NULLPointerException。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-09
    • 2021-09-07
    • 1970-01-01
    • 2016-06-07
    • 2013-04-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多