如何在Android上的后台线程上运行代码?

use*_*987 109 multithreading android

我想要一些代码在后台持续运行.我不想在服务中这样做.还有其他方法吗?

我曾尝试Thread在我的课程中调用课程,Activity但我的Activity遗体在后台停留了一段时间然后停止了.该Thread课程也停止工作.

class testThread implements Runnable {
        @Override
        public void run() {
            File file = new File( Environment.getExternalStorageDirectory(), "/BPCLTracker/gpsdata.txt" );
            int i = 0;

            RandomAccessFile in = null;

            try {
                in = new RandomAccessFile( file, "rw" );
            } catch (FileNotFoundException e) {
// TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
// TODO Auto-generated catch block
                e.printStackTrace();
            }
//String line =null;
            while ( true ) {
                HttpEntity entity = null;
                try {
                    if ( isInternetOn() ) {
                        while ( ( line = in.readLine() ) != null ) {

                            HttpClient client = new DefaultHttpClient();
                            String url = "some url";
                            HttpPost request = new HttpPost( url );
                            StringEntity se = new StringEntity( line );
                            se.setContentEncoding( "UTF-8" );
                            se.setContentEncoding( new BasicHeader( HTTP.CONTENT_TYPE, "application/json" ) );
                            entity = se;
                            request.setEntity( entity );
                            HttpResponse response = client.execute( request );
                            entity = response.getEntity();
                            i++;
                        }
                        if ( ( line = in.readLine() ) == null && entity != null ) {
                            file.delete();
                            testThread t = new testThread();
                            Thread t1 = new Thread( t );
                            t1.start();
                        }


                    } else {
                        Thread.sleep( 60000 );
                    } // end of else

                } catch (NullPointerException e1) {
                    e1.printStackTrace();
                } catch (InterruptedException e2) {
                    e2.printStackTrace();
                } catch (IOException e1) {
// TODO Auto-generated catch block
                    e1.printStackTrace();
                }
            }// end of while
        }// end of run

    }
Run Code Online (Sandbox Code Playgroud)

Bra*_*ude 339

如果你需要:

  1. 在后台线程上执行代码

  2. 执行不触及/更新UI的代码

  3. 执行(短)代码,最多需要几秒钟才能完成

然后使用以下干净且高效的模式,它使用AsyncTask:

AsyncTask.execute(new Runnable() {
   @Override
   public void run() {
      //TODO your background code
   }
});
Run Code Online (Sandbox Code Playgroud)

  • 注意:需要API级别11 (9认同)
  • 注意:[AsyncTask 在 API 级别 R 中已弃用](https://developer.android.com/reference/android/os/AsyncTask) (9认同)
  • 为什么不使用更轻量级的以下内容:new Thread(new Runnable(){@Override public void run(){// background code}}).start(); (7认同)
  • 即使您想更新 UI,您也可以在 run 中使用以下代码片段:activity.runOnUiThread(new Runnable() { @Override public void run() { //Update UI } }); (3认同)
  • 是否有可能导致内存泄漏? (2认同)
  • 要注意的一件事是AsyncTasks已排队。如果将此用于一堆服务器api调用,则它们将不会并行运行。 (2认同)

San*_*p P 40

对于长期后台进程,线程不是Android的最佳选择.但是,这是代码并自行承担风险......

记住服务或线程会在后台运行,但我们的任务需要触发(一次次给),以获取更新,即一旦任务完成,我们需要召回下次更新的功能.

定时器(周期性触发),报警(时基触发),广播(事件基础触发),递归将唤醒我们的功能.

public static boolean isRecursionEnable = true;

void runInBackground() {
    if (!isRecursionEnable)
        // Handle not to start multiple parallel threads
        return;

    // isRecursionEnable = false; when u want to stop
    // on exception on thread make it true again  
    new Thread(new Runnable() {
        @Override
        public void run() {
            // DO your work here
            // get the data
            if (activity_is_not_in_background) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        // update UI
                        runInBackground();
                    }
                });
            } else {
                runInBackground();
            }
        }
    }).start();
}
Run Code Online (Sandbox Code Playgroud)


Jos*_*ter 29

简单的 3-Liner

我在Brandon Rude 的回答中发现了@awardak的评论,这是一种简单的方法:

new Thread( new Runnable() { @Override public void run() { 
  // Run whatever background code you want here.
} } ).start();
Run Code Online (Sandbox Code Playgroud)

我不确定这是否或如何比使用更好,AsyncTask.execute但它似乎对我们有用。任何关于差异的评论将不胜感激。

谢谢,@awardak


Sim*_*iak 22

我想要一些代码在后台持续运行.我不想在服务中这样做.还有其他方法吗?

您正在寻找的最有可能的机制是AsyncTask.它直接指定用于在后台线程上执行后台处理.此外,它的主要优点是提供了一些在Main(UI)线程上运行的方法,如果您想要告知用户任务中的某些进度或使用从后台进程检索的数据更新UI,则可以更新UI.

如果您不知道如何从这里开始是很好的教程:

注:也有可能使用IntentServiceResultReceiver该作品,以及.


Qaz*_*han 6

今天我正在寻找这个,布兰登鲁德先生给出了一个很好的答案。不幸的是,AsyncTask现在已弃用,您仍然可以使用它,但它会给您一个非常烦人的警告。所以另一种方法是Executors像这样使用(在kotlin):


    val someRunnable = object : Runnable{
      override fun run() {
        // todo: do your background tasks
        requireActivity().runOnUiThread{
          // update views / ui if you are in a fragment
        };
        /*
        runOnUiThread {
          // update ui if you are in an activity
        }
        * */
      }
    };
    Executors.newSingleThreadExecutor().execute(someRunnable);

Run Code Online (Sandbox Code Playgroud)

而在java它看起来像这样:


        Runnable someRunnable = new Runnable() {
            @Override
            public void run() {
                // todo: background tasks
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        // todo: update your ui / view in activity
                    }
                });

                /*
                requireActivity().runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        // todo: update your ui / view in Fragment
                    }
                });*/
            }
        };

        Executors.newSingleThreadExecutor().execute(someRunnable);
Run Code Online (Sandbox Code Playgroud)