Good day. There is a method that works when the application starts:

void loadFile() throws IOException { AssetManager am = getAssets(); InputStream inputStream = am.open("text.txt"); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); while ((line = reader.readLine()) != null) { if(line.equals("===")){ arr_full.add(toarr); toarr = ""; }else { toarr = toarr.concat(line).concat("\n"); } } reader.close(); } 

Since the file is too big (3.89 mb), launching the application takes up to 3-5 seconds. Please tell me how to execute this method in another thread so that the main UI thread runs without delay. Thank.

UPD

MyApp.java

 import android.app.Application; import android.content.res.AssetManager; import android.os.AsyncTask; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; public class MyApp extends Application { String line; String toarr = ""; ArrayList<String> arr = new ArrayList<>(); ArrayList<String> arr_full = new ArrayList<>(); int i, j, page; LoadFile lf; void loadFile() throws IOException { AssetManager am = getAssets(); InputStream inputStream = am.open("text.txt"); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); while ((line = reader.readLine()) != null) { if(line.equals("===")){ arr_full.add(toarr); toarr = ""; }else { toarr = toarr.concat(line).concat("\n"); } } reader.close(); } @Override public void onCreate() { super.onCreate(); MySingleton.initInstance(); if(MySingleton.getArr().size() == 0){ lf = new LoadFile(); lf.execute(); } } class LoadFile extends AsyncTask<Void, Void, Void> { @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected Void doInBackground(Void... params) { try { loadFile(); } catch (IOException e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(Void result) { super.onPostExecute(result); MySingleton.setArr(arr_full); } } } 

Log

 08-22 20:16:34.107 518-518/com.app.app D/myLogs: запуск onPreExecute чтения файла 08-22 20:16:34.117 518-558/com.app.app D/myLogs: запуск doInBackground чтения файла 08-22 20:16:34.985 518-518/com.app.app D/myLogs: запуск onPreExexute парсера 08-22 20:16:37.862 518-518/com.app.app D/myLogs: запуск onPostExecute чтения файла 08-22 20:16:39.971 518-676/com.app.app D/myLogs: запуск doInBackground парсера 08-22 20:16:40.785 518-518/com.app.app D/myLogs: запуск onPostExecute парсера 

    1 answer 1

    You can perform background work using AsyncTask , IntentService , Service . Below, I gave an example of a class of an AsyncTask that can do background work in the doInBackground method. If for some reason this option does not suit you, I can add an option with an IntentService or Service to the answer

     class MyTask extends AsyncTask<Void, Void, Void> { @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected Void doInBackground(Void... params) { AssetManager am = getAssets(); InputStream inputStream = am.open("text.txt"); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); while ((line = reader.readLine()) != null) { if(line.equals("===")){ arr_full.add(toarr); toarr = ""; }else { toarr = toarr.concat(line).concat("\n"); } } reader.close(); return null; } @Override protected void onPostExecute(Void result) { super.onPostExecute(result); tvInfo.setText("End"); } } } 

    and you can call it like this:

     new MyTask.execute(); 

    Example IntentService from official documentation .

    At the start of the service - we throw into it an Intent with an action. In the service it gets into the onHandleIntent() method in it, you can determine what needs to be done (call some kind of method) by an action. Each such Intent starts a new thread, which will be closed after your code runs.

     * * Creates a new Intent to start the RSSPullService * IntentService. Passes a URI in the * Intent's "data" field. */ mServiceIntent = new Intent(getActivity(), RSSPullService.class); mServiceIntent.setData(Uri.parse(dataUrl)); mServiceIntent.setAction("YOUR_ACTION"); // Starts the IntentService getActivity().startService(mServiceIntent); 

    RSSPullService.java

     public class RSSPullService extends IntentService { @Override protected void onHandleIntent(Intent intent) { //достаем action String action = intent.getAction(); ... // достаем данные из интента String dataString = intent.getDataString(); ... switch(action){ case "YOUR_ACTION": //сделать что то там... } } } 

    And do not forget to register the service in Manifest.xml

      <application android:icon="@drawable/icon" android:label="@string/app_name"> ... <!-- Because android:exported is set to "false", the service is only available to this app. --> <service android:name=".RSSPullService" android:exported="false"/> ... <application/> 

    The Service example is described in detail in the official documentation. I will not copy the code from there, just note that the main difference from the IntentService is that you need to manage the life cycle of the service yourself, in the sense that when you start the service, it does not stop.

    • AsyncTask principle is suitable, but I already have one AsyncTask in my application for working with the Internet. Now added a second AsyncTask to download the file and it AsyncTask that the second (for the Internet) does not start until the first one (download the file). - Pollux
    • Ideally, this should not be, since the name AsyncTask itself says that these tasks are asynchronous, but I can’t say for sure without sample code! - Kirill Stoianov
    • The code is very large, so I’ll give some highlights. In the application I use the singleton class, which is launched via MyApp.java (so that the singleton is not destroyed from the activation change. I updated the first post). In MyApp.java added AsyncTask , in which the file is loaded and added to the singleton. In the MainActivity in onCreate(Bundle savedInstanceState) , the second AsyncTask and the AsyncTask library is Jsoup , which parses the site data ... // - Pollux
    • // ... It is possible that when a file is loaded, this loadFile() method "eats" many smartphone resources, as a result of which the second AsyncTask seems to be AsyncTask longer. But I guess so) - Pollux
    • Try logging in both asintasks in the methods onPreExecute, doInBackground, onPostExecute and see what happens when it is called - Kirill Stoianov