从广播接收器android调用AsyncTask

Chr*_*ray 7 java android broadcastreceiver android-asynctask

所以当前我有一个AsyncTask类,当我点击一个按钮时,它运行和POST的数据到我的服务器(效果很好).

我现在尝试做的是处理用户未连接到互联网时发生的情况.所以我设置了这些类,以便在互联网连接时通知应用程序,以便数据可以自动发送到服务器.

AsyncTask类(内部类)

 private class HttpAsyncTask extends AsyncTask<String, Void, String> {

    ProgressDialog dialog = new ProgressDialog(getActivity());
    final AlertDialog finishedDialog = new AlertDialog.Builder(getActivity())
    .setCancelable(false)
    .setPositiveButton(android.R.string.ok, null)
    .create();



    @Override
    protected String doInBackground(String... urls) {
        onProgressUpdate("Uploading Data...");
        return POST(urls[0]);
    }

    @Override
    protected void onPreExecute() {
        this.dialog.show();
        finishedDialog.setOnShowListener(new DialogInterface.OnShowListener(){

            @Override
            public void onShow(DialogInterface dialog) {
                Button b = finishedDialog.getButton(AlertDialog.BUTTON_POSITIVE);
                b.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    // navigate to match summary.....
                    finishedDialog.dismiss();
                }

            });
            }

        });
    }

    protected void onProgressUpdate(String msg) {
        dialog.setMessage(msg);

    }

    // onPostExecute displays the results of the AsyncTask.
    @Override
    protected void onPostExecute(String result) {
        if (result != ""){

            finishedDialog.setTitle("Upload Complete!");
            finishedDialog.setMessage("Data Sent Successfully");
            finishedDialog.show();
            dialog.dismiss();
            editor.clear();
            editor.commit();
            //Toast.makeText(getActivity().getBaseContext(), result, Toast.LENGTH_LONG).show();
        }else
        {
            Handler handler = new Handler();
            handler.postDelayed(new Runnable() {
                public void run() {
                    finishedDialog.setTitle("Upload Failed!");
                    finishedDialog.setMessage("Data Will Automatically Be Uploaded When Internet Connection Is Available");
                    finishedDialog.show();
                    dialog.dismiss();
                }}, 1000);

            setFlag(true);
        }
   }

}


public static boolean getFlag() {
    return flag;
}

public void setFlag(boolean flag) {
    this.flag = flag;
}


public String POST(String url){
    InputStream inputStream = null;
    String result = "";
    try {

        // 1. create HttpClient
        HttpClient httpclient = new DefaultHttpClient();

        // 2. make POST request to the given URL
        HttpPost httpPost = new HttpPost(url);


        if(adapter.updateNeeded()){
            JSONObject main = new JSONObject(exmaplePrefs.getString("jsonString", "cant find json"));
            JSONObject dbUpdates = new JSONObject(exmaplePrefs.getString("ChangesJSON", "cant find Changejson"));
            main.put("Team_Updates", dbUpdates);
            json = main.toString();
        }else{
             json = exmaplePrefs.getString("jsonString", "cant find json");
             // String json = "{\"twitter\":\"test\",\"country\":\"test\",\"name\":\"test\"}";
        }




        // 5. set json to StringEntity
        StringEntity se = new StringEntity(json);
        se.setContentType("application/json;charset=UTF-8");

        // 6. set httpPost Entity
        httpPost.setEntity(se);

        // 7. Set some headers to inform server about the type of the content   
       // httpPost.setHeader("Accept", "application/json");
       // httpPost.setHeader("Content-type", "application/json");
       // httpPost.setHeader("json", json);


        // 8. Execute POST request to the given URL

        HttpResponse httpResponse = httpclient.execute(httpPost);

        // 9. receive response as inputStream
        inputStream = httpResponse.getEntity().getContent();

        String status = httpResponse.getStatusLine().toString();
        // 10. convert inputstream to string
        if (!status.equals("HTTP/1.1 500 Internal Server Error")){
            if(inputStream != null){
                result = convertInputStreamToString(inputStream);   
            }
            else{
                result = "Did not work!";
            }
        }else{
            System.out.println("500 Error");

        }



    } catch (Exception e) {
        Log.d("InputStream", e.getLocalizedMessage());
        System.out.println("eerroorr "+e);
    }

    // 11. return result
    System.out.println(result);
    return result;

}

private static String convertInputStreamToString(InputStream inputStream) throws IOException{
    BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(inputStream));
    String line = "";
    String result = "";
    while((line = bufferedReader.readLine()) != null)
        result += line;

    inputStream.close();
    return result;

}
}
Run Code Online (Sandbox Code Playgroud)

NetworkUtil类

  public class NetworkUtil {

public static int TYPE_WIFI = 1;
public static int TYPE_MOBILE = 2;
public static int TYPE_NOT_CONNECTED = 0;


public static int getConnectivityStatus(Context context) {
    ConnectivityManager cm = (ConnectivityManager) context
            .getSystemService(Context.CONNECTIVITY_SERVICE);

    NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
    if (null != activeNetwork) {
        if(activeNetwork.getType() == ConnectivityManager.TYPE_WIFI)
            return TYPE_WIFI;

        if(activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE)
            return TYPE_MOBILE;
    }
    return TYPE_NOT_CONNECTED;
}

public static String getConnectivityStatusString(Context context) {
    int conn = NetworkUtil.getConnectivityStatus(context);
    String status = null;
    if (conn == NetworkUtil.TYPE_WIFI) {
        status = "Wifi enabled";
    } else if (conn == NetworkUtil.TYPE_MOBILE) {
        status = "Mobile data enabled";
    } else if (conn == NetworkUtil.TYPE_NOT_CONNECTED) {
        status = "Not connected to Internet";
    }
    return status;
}
}
Run Code Online (Sandbox Code Playgroud)

BroadcastReceiver类

public class NetworkChangeReceiver extends BroadcastReceiver {


@Override
public void onReceive(final Context context, final Intent intent) {
     intent.getExtras();
    String status = NetworkUtil.getConnectivityStatusString(context);

    Toast.makeText(context, status, Toast.LENGTH_LONG).show();

    if(MatchFragment.getFlag()){
        //send data
    }
}
}
Run Code Online (Sandbox Code Playgroud)

因此,在BroadcastReceiver类中,当应用程序尝试发送数据但没有Internet(AsyncTask类中的onPostExecute)时,我会检查设置为true的标志.

所以想要做的是如何调用POST方法.我是否必须创建一个新的Async任务类?我有点难过这里.

谢谢

Quo*_*oon 11

使用AsyncTaskin BroadcastReceiver是一种不好的做法.

您应该使用,Service因为Android操作系统可能onReceive()会终止您的进程或可能会在asyncTask返回结果之前运行完成,因此无法保证您将获得预期的结果.


ren*_*een 5

您不应该在Broadcast Receiver中使用AsyncTask,因为系统可以在从onReceive方法返回后终止您的进程(如果没有任何活动服务或活动). 证明链接

官方文档建议针对此类情况使用 IntentService(请参阅有关广​​播接收器的段落).


Hyp*_*cle 5

根据 Google 的文档,其他答案不正确。该广播接收机开发人员指南明确要求了,您可以使用AsyncTask期从BroadcastReceiver■如果你调用goAsync()第一和状态报告给未决结果在AsyncTask

因此,您不应从广播接收器启动长时间运行的后台线程。在 onReceive() 之后,系统可以随时终止进程以回收内存,并在这样做时终止在进程中运行的衍生线程。为避免这种情况,您应该调用 goAsync()(如果您想要更多时间在后台线程中处理广播)或使用 JobScheduler 从接收器调度 JobService,以便系统知道该进程继续执行活动工作。

后来它阐明了您实际获得的时间:

在接收器的 onReceive() 方法中调用 goAsync() 并将 BroadcastReceiver.PendingResult 传递给后台线程。这使广播在从 onReceive() 返回后保持活动状态。但是,即使采用这种方法,系统也希望您能很快(不到 10 秒)完成广播。它确实允许您将工作转移到另一个线程以避免主线程出现故障。

public class MyBroadcastReceiver extends BroadcastReceiver {
    private static final String TAG = "MyBroadcastReceiver";

    @Override
    public void onReceive(final Context context, final Intent intent) {
        final PendingResult pendingResult = goAsync();
        AsyncTask<String, Integer, String> asyncTask = new AsyncTask<String, Integer, String>() {
            @Override
            protected String doInBackground(String... params) {
                StringBuilder sb = new StringBuilder();
                sb.append("Action: " + intent.getAction() + "\n");
                sb.append("URI: " + intent.toUri(Intent.URI_INTENT_SCHEME).toString() + "\n");
                Log.d(TAG, log);
                // Must call finish() so the BroadcastReceiver can be recycled.
                pendingResult.finish();
                return data;
            }
        };
        asyncTask.execute();
    }
}
Run Code Online (Sandbox Code Playgroud)