Android 在服务内部运行方法而不干扰主UI线程的最佳方法

Android 在服务内部运行方法而不干扰主UI线程的最佳方法,android,multithreading,service,android-handler,Android,Multithreading,Service,Android Handler,我有一个方法,从电话中获取联系人,并将其发送到php服务器进行处理,然后它将返回数据,以便在sql lite数据库中进行更新。我需要在后台连续运行此方法。我正在使用截击进行网络操作。我正在使用服务内部的处理程序来运行此方法。问题是我看到过太多的跳帧,而且应用程序速度非常慢,而且很笨拙。我希望在不干扰主线程的情况下运行此方法。服务代码如下所述 public class serv extends Service { ArrayList<String> aa= new ArrayList

我有一个方法,从电话中获取联系人,并将其发送到php服务器进行处理,然后它将返回数据,以便在sql lite数据库中进行更新。我需要在后台连续运行此方法。我正在使用截击进行网络操作。我正在使用服务内部的处理程序来运行此方法。问题是我看到过太多的跳帧,而且应用程序速度非常慢,而且很笨拙。我希望在不干扰主线程的情况下运行此方法。服务代码如下所述

public class serv extends Service {

ArrayList<String> aa= new ArrayList<>();
ArrayList<String> bb= new ArrayList<>();
JSONObject JSONimdb;
JSONObject EverythingJSON;
ArrayList<mobstat> musers = new ArrayList<mobstat>();
private RequestQueue requestQueue;
String l;
private static Timer timer = new Timer();

@Override
public void onTaskRemoved(Intent rootIntent) {
    Log.e("Shiva","Service Killed");
}

@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
//nonstop1();
 threadcheck();
    return Service.START_STICKY;
}

private void _startService()
{
    long UPDATE_INTERVAL = 5 * 1000;
    timer.scheduleAtFixedRate(
    new TimerTask()
    {
       public void run()
       {
         try
          {
            getNumber(serv.this.getContentResolver());
          } catch (JSONException e)
          {
            e.printStackTrace();
          }
          }
          }, 1000, UPDATE_INTERVAL);
 }

private void nonstop1()
{
   final Handler handlera = new Handler();
    Runnable updatea = new Runnable()
    {
        @Override
        public void run()
        {

            try {
                getNumber(serv.this.getContentResolver());
            } catch (JSONException e) {
                e.printStackTrace();
            }
            handlera.postDelayed(this , 1000);
        }
    };
    handlera.postDelayed(updatea, 10);
}

private void threadcheck()
{
    new Thread() {
         public void run() {
            try {
                Log.e("Shiva","Threadcheck");
                getNumber(serv.this.getContentResolver());
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }.start();
}
@Override
public void onDestroy()
{
    super.onDestroy();
   // Intent broadcatIntent = new Intent("com.statmob.findnum");
    //sendBroadcast(broadcatIntent);
    //stoptimertask();
  //nonstop1();
   threadcheck();
}



public void getNumber(ContentResolver cr) throws JSONException
{
    Cursor phones = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null,null, null);
    while (phones.moveToNext())
    {
        String name=phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
        String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
        if (phoneNumber.length()>=10)
        {
          l = phoneNumber.substring(phoneNumber.length()-10);
          aa.add(l);
          bb.add(name);}
    }
    phones.close();

    JSONimdb = new JSONObject();
    for (int i = 0; i < aa.size(); i++)
    {
      try
       {
         JSONimdb.put(bb.get(i), aa.get(i));
       } catch (JSONException e)
         {
           e.printStackTrace();
         }
    }

    EverythingJSON = new JSONObject();
    try
      {
        EverythingJSON.put("imdblist", JSONimdb);
      } catch (JSONException e)
        {
          e.printStackTrace();
        }

   StringRequest stringRequest = new StringRequest(Request.Method.POST, "http://xxxxxxxx/cont.php",
            new Response.Listener<String>()
            {
                @Override
                public void onResponse(String s)
                {
                  if (s != null)
                  {
                    parseJSONresponse(s);
                  }
                }
            },
            new Response.ErrorListener()
            {
                @Override
                public void onErrorResponse(VolleyError error)
                {
                  Log.e("Shiva",""+error);
                }
            }) {
                @Override
                protected Map<String, String> getParams() throws AuthFailureError
                {
                  Map<String, String> params = new Hashtable<String, String>();
                  params.put("arr", EverythingJSON.toString());
                  return params;
                }
            };

    int socketTimeout = 50000;
    RetryPolicy policy = new DefaultRetryPolicy(socketTimeout,
    DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
    if(requestQueue==null)
    {
      requestQueue = Volley.newRequestQueue(serv.this);}
      stringRequest.setRetryPolicy(policy);
      requestQueue.add(stringRequest);
    }

private void parseJSONresponse(String s)
{
   try
      {
        JSONArray json = new JSONArray(s);

        for (int i = 0; i < json.length(); i++)
        {
          JSONObject e = json.getJSONObject(i);
          musers.add(new mobstat(e.getString("name"), e.getString("status"),e.getLong("time")));
          SugarRecord.updateInTx(musers);

        }
    } catch (JSONException e)
      {
        e.printStackTrace();
      }
    }
 }
公共类服务扩展服务{
ArrayList aa=新的ArrayList();
ArrayList bb=新的ArrayList();
JSONObject JSONimdb;
JSONObject EverythingJSON;
ArrayList musers=新的ArrayList();
私有请求队列请求队列;
字符串l;
专用静态计时器=新计时器();
@凌驾
公共void onTaskRemoved(Intent rootIntent){
Log.e(“湿婆”,“服务终止”);
}
@可空
@凌驾
公共IBinder onBind(意向){
返回null;
}
@凌驾
公共int onStartCommand(Intent Intent、int标志、int startId)
{
//nonstop1();
螺纹检查();
return Service.START\u STICKY;
}
私有void_startService()
{
长更新间隔=5*1000;
timer.scheduleAtFixedRate(
新TimerTask()
{
公开募捐
{
尝试
{
getNumber(serv.this.getContentResolver());
}捕获(JSONException e)
{
e、 printStackTrace();
}
}
},1000,更新间隔);
}
私有void nonstop1()
{
最终处理程序handlera=新处理程序();
Runnable updatea=new Runnable()
{
@凌驾
公开募捐
{
试一试{
getNumber(serv.this.getContentResolver());
}捕获(JSONException e){
e、 printStackTrace();
}
handlera.postDelayed(这是1000);
}
};
handlera.postDelayed(更新a,10);
}
私有void threadcheck()
{
新线程(){
公开募捐{
试一试{
Log.e(“湿婆”,“螺纹检查”);
getNumber(serv.this.getContentResolver());
}捕获(JSONException e){
e、 printStackTrace();
}
}
}.start();
}
@凌驾
公共空间
{
super.ondestory();
//Intent broadcatIntent=新Intent(“com.statmob.findnum”);
//发送广播(广播内容);
//stoptimertask();
//nonstop1();
螺纹检查();
}
public void getNumber(ContentResolver cr)抛出JSONException
{
游标phones=cr.query(ContactsContract.CommonDataTypes.Phone.CONTENT\u URI,null,null,null,null);
while(phones.moveToNext())
{
字符串名称=phones.getString(phones.getColumnIndex(ContactsContract.CommonDataTypes.Phone.DISPLAY_name));
String phoneNumber=phones.getString(phones.getColumnIndex(ContactsContract.CommonDataTypes.Phone.NUMBER));
如果(phoneNumber.length()>=10)
{
l=phoneNumber.substring(phoneNumber.length()-10);
aa.加入(l);
bb.add(name);}
}
电话。关闭();
JSONimdb=新的JSONObject();
对于(int i=0;i

我试过定时器和处理器,它们工作正常,但它使应用程序速度慢,没有响应。线程不工作。请建议一些更好的方法在后台运行此方法,而不会对主线程造成任何干扰。

在清单文件中为您的服务创建单独的进程,这可能会对您有所帮助

<manifest>
....
<application>
.....
 <service android:name=".serv"  android:process=":myprocess"  >
</application>
</manifest>

....
.....

你试过了吗?这是一种运行耗时的后台任务的简单方法。

使用
IntentServices
修改当前的实现

默认情况下,
IntentServices
在后台线程中运行。如果使用
服务
,则默认情况下使用主线程。然后你需要运行一个
线程
内部服务到mak