使用齐射将数据发布到服务器时,JobService无法正常工作

时间:2017-11-02 05:27:40

标签: android sqlite android-volley jobservice

我正在尝试将SQLite数据与mysql同步,因为这个创建的JobService每15秒同步一次数据(仅同步那些与mysql状态不同步的数据)。这与localhost(xampp服务器)完美配合。 但Web服务器出现问题:每15秒JobService会产生重复的条目。

MyService.java

    public class MyService extends JobService {

    private DatabaseHelper db;
    SQLiteDatabase sqLiteDatabase;

    private Handler mJobHandler = new Handler( new Handler.Callback() {
        @Override
        public boolean handleMessage( Message msg ) {
            Toast.makeText( getApplicationContext(), "JobService task running", Toast.LENGTH_SHORT ).show();
            jobFinished( (JobParameters) msg.obj, false );
            return true;
        }
    } );

    @Override
    public boolean onStartJob(JobParameters params ) {
        mJobHandler.sendMessage( Message.obtain( mJobHandler, 1, params ) );
        db = DatabaseHelper.getInstance(getApplicationContext());
        postData();
        //db.close();
        return true;
    }

    @Override
    public boolean onStopJob( JobParameters params ) {
        mJobHandler.removeMessages( 1 );
        return false;
    }

    private void postData() {

        Cursor cursor = db.getUnsyncedNames();
        try {
            if (cursor != null) {

                if (cursor.moveToFirst()) {

                    do {
                        saveName(cursor.getInt(cursor.getColumnIndex(DatabaseHelper.COLUMN_ID)), cursor.getString(cursor.getColumnIndex(DatabaseHelper.COLUMN_FROM_NO)), cursor.getString(cursor.getColumnIndex(DatabaseHelper.COLUMN_TO_NO)));
                    } while (cursor.moveToNext());
                }
            }
        }  finally {
            if (cursor != null && !cursor.isClosed())
                cursor.close();
            db.close();
        }
    }

    private void saveName(final int id, final String fromNo, final String toNo) {
        StringRequest stringRequest = new StringRequest(Request.Method.POST, Config.URL_REQUEST_SMS,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        try {
                            JSONObject obj = new JSONObject(response);
                            if (!obj.getBoolean("error")) {
                                //updating the status in sqlite
                                db.updateNameStatus(id,NAME_SYNCED_WITH_SERVER);

                                sqLiteDatabase = db.getWritableDatabase();
                                if (sqLiteDatabase != null) {
                                    sqLiteDatabase.delete(DatabaseHelper.TABLE_NAME, null, null);
                                }
                               // db.close();

                                Toast.makeText(getApplicationContext(),"Unsynced no. submitted!",Toast.LENGTH_LONG).show();

                                //calls.clear();

                            }
                        } catch (JSONException e) {
                            e.printStackTrace();

                            Toast.makeText(getApplicationContext(),"JSONException error1 : "+e,Toast.LENGTH_LONG).show();

                        }
                        finally {
                            db.close();
                        }
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Toast.makeText(getApplicationContext(),"VolleyError error2 : "+error,Toast.LENGTH_LONG).show();
                        error.printStackTrace();
                    }
                }) {
            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
                Map<String, String> params = new HashMap<>();
                params.put("mobile", fromNo);
                params.put("toMob", toNo);
                return params;
            }
        };

                int socketTimeout = 60000;
                RetryPolicy policy = new DefaultRetryPolicy(socketTimeout,
                        DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                        DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
                stringRequest.setRetryPolicy(policy);

        MyApplication.getInstance().addToRequestQueue(stringRequest);
    }
}

MainActivity.java

  JobInfo.Builder builder = new JobInfo.Builder( 1,
            new ComponentName( getPackageName(), MyService.class.getName() ) );

    builder.setPeriodic(15000);

我的logcat也显示

  

E / Surface:getSlotFromBufferLocked:未知缓冲区:0x7f517cd1b540

2 个答案:

答案 0 :(得分:1)

是的,我有同样的问题,结果是凌空一次分配内存,没有取消分配内存。它会耗尽内存并强制执行操作系统GC,这将停止所有此类服务,移动到Retrofit 2,使作业服务完美运行

最好的解决方案是改进2.我们进行了压力测试

答案 1 :(得分:0)

您的处理程序正在规避整个JobService流程。它将作业标记为已成功完成,甚至尚未完成。

我发现所提供的代码存在多个问题:

  • 所有数据库逻辑都在主线程而不是后台线程上发生。
  • 您正在为每个作业创建一个新的数据库连接。
  • 您正在泄漏数据库连接(因为您没有在try块内连接或运行查询)。

我真的不认为您的问题是Volley。