仅启动一次后台服务,并在任务完成后停止

Posted

技术标签:

【中文标题】仅启动一次后台服务,并在任务完成后停止【英文标题】:Starting a background service for only once and stop once the task is completed 【发布时间】:2016-08-12 15:36:07 【问题描述】:

我在我的活动中使用自动完成文本视图,并且我编写了一个服务以在完成服务后从同一活动中的服务器获取数据我启用了该自动完成文本视图,因为当用户开始在该文本视图中输入我从服务器开始获得的数据得到过滤,到这里的每件事都工作正常,但每次我进入相同的活动时,我的服务开始执行我只希望我的服务只被调用一次,并且用户可以从自动完成中搜索我的数据来自服务器后的文本视图。

我的活动代码

@Override
 protected void onStart() 



    if(CarproApp.getInstance().namesList != null) 
    //enable textfield if you have already fetched the data from server :)
        debitornameET.setEnabled(true);
    else
        myReceiver = new MyReceiver();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(MyService.MY_ACTION);
        registerReceiver(myReceiver, intentFilter);
        //Start our own service

    

    Intent intent = new Intent(CustomerAccountActivity.this,
            MyService.class);
    //intent.putExtra("INIT_DATA", "Data passed from Activity to Service in startService");
    startService(intent);
    super.onStart();


@Override
protected void onStop() 
    unregisterReceiver(myReceiver);
    super.onStop();


private class MyReceiver extends BroadcastReceiver 

    @Override
    public void onReceive(Context arg0, Intent arg1) 
        namelist = arg1.getStringArrayListExtra("listnames");
        System.out.println("PRINTING" + namelist);
        debitornameET.setEnabled(true);
        Toast.makeText(getApplicationContext(), "BackGround Task   Completed", Toast.LENGTH_SHORT).show();
        CarproApp.getInstance().namesList = namelist;

    

   debitornameET.addTextChangedListener(new TextWatcher() 

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) 

            runOnUiThread(new Runnable() 
                public void run() 

                    //  MyWebRequestService.listVal; 
                    debitorcodeET.setText("");
                    debitorCode = "";
                    Collections.sort(namelist);//here i am getting null when i came back to same activity
                    ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_dropdown_item_1line,namelist);
                    dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
                    debitornameET.setThreshold(1);
                    debitornameET.setAdapter(dataAdapter);


                
            );
        

Service.Class

 public class MyService extends Service 

    final public static String MY_ACTION = "MY_ACTION";
    //String initData;
    private SendHttpRequest reqService;
    public static ArrayList<String> servicelist;  

    @Override
    public IBinder onBind(Intent arg0) 

        return null;
    

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) 

        servicelist = new ArrayList<String>();
    //  initData = intent.getStringExtra("INIT_DATA");

        new AsynchCall().execute();

        return super.onStartCommand(intent, flags, startId);
    


    class AsynchCall extends AsyncTask<String,String,String>

        @Override
        protected String doInBackground(String... params) 
            String qryService = "SELECT DEBITOR_NAME FROM DEBITORS ";
            reqService = new SendHttpRequest(qryService);
            try 
                reqService.ExecuteQuery();
             catch (URISyntaxException e) 
                e.printStackTrace();
             catch (IOException e) 
                e.printStackTrace();
             catch (ParserConfigurationException e) 
                e.printStackTrace();
             catch (SAXException e) 

                e.printStackTrace();
            

            for(int i=0;i<reqService.getRowCount();i++)
            
                servicelist.add(reqService.getRow(i)[1]);
                System.out.println("TEXTVIEWDATAAAAAAAAa" + reqService.getRow(i)[1]);
            
            Intent intent = new Intent();
            intent.setAction(MY_ACTION);
            intent.putStringArrayListExtra("listnames", servicelist);
            sendBroadcast(intent);
            return null;
        

    

** CarproApp 类**

        public class CarproApp extends Application 

        private static CarproApp sInstance;
        public ArrayList<String> namesList;

        public static CarproApp getInstance() 
            return sInstance;
        

        public void onCreate() 
            super.onCreate();
            sInstance = this;


        



    

因为来自服务器的数据太大,我不希望它存储在本地数据库中。我的代码正在运行,但是每次我开始活动时,都会执行我不想要的服务调用。请指导我

【问题讨论】:

@piyush-daryapurkar :我已经更新了我的答案检查 mainActivity onStart 方法 :) 现在一切都应该没问题 :) 如果你还有问题 :) 让我知道 :) 不应该有 :D 嘿,我已经更新了主要活动的 onStart() 方法和 onTextChanged() :) null 的简单原因 :) 您在 onTextChange 内使用 MainActivity 的 namelist 属性 :) 当您更改时活动并回到相同的活动:) 活动 ke saare 财产重新创建 hogaana ??所以值 null hee rahegana bhai :D 所以使用应用程序实例值 :D 这就是我们添加它的原因记得吗? :D kya hua bhai ??查拉代码??现在一切都好吗??? @SandeepBhandari 兄弟在犯了所有愚蠢的错误之后(kolaveri di)我让你的代码像魅力一样工作,非常感谢你让我知道我的输出,谢谢你所有的努力.. :) :) 【参考方案1】:

利用 Application 类 :) Application 类在应用程序的整个生命周期中执行一次 :) 这意味着应用程序类的 onCreate 会在您启动应用程序时被调用,而 onDestroy 会在您终止应用程序时被调用 :)

所以 Application 类在您的应用程序的整个生命周期中都是持久的 :) 我相信这就是您所需要的 :)

在您的应用程序类的 OnCreate() 中调用您的服务 :) 一旦您获得数据,将其保存在 Application 类的属性中 :) 因此,每当您回到 Activity 时,从 Application 类的属性中读取数据 :)

这是你可以做的:)

public class yourApplicationName extends Application 
     private static yourApplicationName sInstance;
     public ArrayList<String> namesList;

     public static yourApplicationName getInstance() 
        return sInstance;
    

    public void onCreate() 
        super.onCreate();
        sInstance = this;
    

为了将此应用程序类用作您的应用程序类,您必须在 AndroidManifest.xml 中指定它:)

<application
    android:name=".yourApplicationName"

在你的,

私有类 MyReceiver 扩展 BroadcastReceiver

@Override
public void onReceive(Context arg0, Intent arg1) 
    namelist = arg1.getStringArrayListExtra("listnames");
    System.out.println("PRINTING" + namelist);
    debitornameET.setEnabled(true);
    Toast.makeText(getApplicationContext(), "BackGround Task         Completed", Toast.LENGTH_SHORT).show();
    yourApplicationName.getInstance().namesList = nameList;


debitornameET.addTextChangedListener(new TextWatcher() 

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) 

        runOnUiThread(new Runnable() 
            public void run() 

                //  MyWebRequestService.listVal; 
                debitorcodeET.setText("");
                debitorCode = "";
                Collections.sort(CarproApp.getInstance().namesList);//here i am getting null when i came back to same activity, abhi nai aayega error :P
                ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_dropdown_item_1line,CarproApp.getInstance().namesList);
                dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
                debitornameET.setThreshold(1);
                debitornameET.setAdapter(dataAdapter);


            
        );
    

要在您返回 MainActivity 时启用您的文本字段 :) 只需检查 Application 实例属性是否为空 :)

  @Override
  protected void onStart() 
       if(yourApplicationName.getInstance().namesList != null) 
            //enable textfield if you have already fetched the data from server :)
            debitornameET.setEnabled(true);
       
       else
            myReceiver = new MyReceiver();
            IntentFilter intentFilter = new IntentFilter();
            intentFilter.addAction(MyService.MY_ACTION);
            registerReceiver(myReceiver, intentFilter);

            //you dont have to call service very time buddy :D call only once enough :)
            Intent intent = new Intent(CustomerAccountActivity.this,
        MyService.class);
            //intent.putExtra("INIT_DATA", "Data passed from Activity to Service in startService");
            startService(intent);
       
  

希望我对那里的帮助不大 :) 快乐的编码伙伴 :)

【讨论】:

当你投反对票时请留下评论 :) 帮助我理解我的错误 在这一行中获取空指针 yourApplicationName.getInstance().namesList = namelist; @PiyushDaryapurkar :您是否将 yourApplicationName 设置为您的应用程序类好友?你改变了AndroidManifest.xml ???而且我已经更新了 yourApplicationName 类的 onCreate 方法 :) 能否请您确认已使用更新的代码好友 :) @SandeepBhandari 是的兄弟.. 我已经完全按照你所说的做了我写了一个单独的类并写了你说的方法我也已经在清单中注册了它我在 onStart() 中也得到了空指针如果条件 兄弟,您的 ApplicationName 类的 nameList 属性是否为空?这就是你在说的哥们???

以上是关于仅启动一次后台服务,并在任务完成后停止的主要内容,如果未能解决你的问题,请参考以下文章

TASKCTL4.1后台服务怎么启动?

nodejs服务后台持续运行三种方法

使用 Django 启动和停止定期后台任务

win7任务计划

如何让android的service一直在后台运行

当应用程序进入后台时停止后台服务