0

私は現在、アラームマネージャー、ブロードキャストレシーバー、およびインテントサービスを使用して、Ui メインスレッドの代わりにバックグラウンドでサーバーへのアップロードサービスを実装していますが、問題は実行時に、アップロードメッセージに対する応答がないことです。少なくとも、logcat では、正しく入力してテストしたアップロードの進行状況を報告するメッセージを確認できます。

しかし、アップロード サービスが終了すると、java.lang.RuntimeException: Handler (android.os.Handler) sent message to a Handler on a dead thread が表示されます

他に何が欠けているか教えてください。

以下は私のコードです

Intnt サービス

public class TaskService extends IntentService {

    public TaskService() {
        super("TaskService");
        // TODO Auto-generated constructor stub
    }

    @Override
    protected void onHandleIntent(Intent arg0) {

        // Do some task
        Log.i("TaskService","Service running");
        boolean ss = uploadRecording("TEST_RECORD" , "test.mp4" , "http://210.177.246.83/uploadFile");
        Log.d("Is file uploaded" , String.valueOf(ss));
    }

    public boolean uploadRecording(String directoryname , String filename , String destination) {
        // TODO Auto-generated method stub

        boolean result = false;

        String destinationPath = destination;       

        File tes = new File(Environment.getExternalStorageDirectory() + File.separator + directoryname);
        File frecord = new File(tes.getAbsolutePath() + File.separator + filename);
        if(tes.exists()){
            if(frecord.exists()){

                List< NameValuePair> httpContents = new ArrayList< NameValuePair>();
                httpContents.add(new BasicNameValuePair("file",frecord.getAbsolutePath())); 

                HttpClient client=new DefaultHttpClient();
                HttpPost post=new HttpPost(destinationPath);
                try{
                    //setup multipart entity
                    MultipartEntity entity=new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);

                    for(int i=0;i< httpContents.size();i++){
                        //identify param type by Key
                        if(httpContents.get(i).getName().equals("file")){
                            File f=new File(httpContents.get(i).getValue());
                            FileBody fileBody=new FileBody(f);
                            entity.addPart("file"+i,fileBody);
                        }
                    }
                    post.setEntity(entity);
                    //create response handler
                    //execute and get response
                    HttpResponse uploadReponse = client.execute(post);
                    Log.d("debug" , "Response : " + uploadReponse);
                    if(uploadReponse.getStatusLine().getStatusCode() == 200){
                        result = true;
                        Toast.makeText(getApplicationContext(), "Upload Success", Toast.LENGTH_SHORT).show();
                    }
                }catch(Exception e){
                    e.printStackTrace();
                }     
            }
        }

        return result;       
    }   
}

放送受信機

public static String ACTION_ALARM = "com.alarammanager.alaram";

    @Override
    public void onReceive(Context context, Intent intent) {

        Log.i("Alarm Receiver", "Entered");
        Toast.makeText(context, "Entered", Toast.LENGTH_SHORT).show();

        Bundle bundle = intent.getExtras();
        String action = bundle.getString(ACTION_ALARM);
        if (action.equals(ACTION_ALARM)) {
            Log.i("Alarm Receiver", "If loop");
            Toast.makeText(context, "If loop", Toast.LENGTH_SHORT).show();
            Intent inService = new Intent(context, TaskService.class);
            inService.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startService(inService);
        }
        else
        {
            Log.i("Alarm Receiver", "Else loop");
            Toast.makeText(context, "Else loop", Toast.LENGTH_SHORT).show();
        }
    }

主な活動

public class AlaramScheduleActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

    }

    public void btnStartSchedule(View v) {

        try {
            AlarmManager alarms = (AlarmManager) this
                    .getSystemService(Context.ALARM_SERVICE);

            Intent intent = new Intent(getApplicationContext(),
                    AlaramReceiver.class);
            intent.putExtra(AlaramReceiver.ACTION_ALARM,
                    AlaramReceiver.ACTION_ALARM);

            final PendingIntent pIntent = PendingIntent.getBroadcast(this,
                    1234567, intent, PendingIntent.FLAG_UPDATE_CURRENT);

            alarms.setRepeating(AlarmManager.RTC_WAKEUP,
                    System.currentTimeMillis(), 1000 * 10, pIntent);

            toast("Started...");

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    public void btnCancelSchedules(View v) {

        Intent intent = new Intent(getApplicationContext(),
                AlaramReceiver.class);
        intent.putExtra(AlaramReceiver.ACTION_ALARM,
                AlaramReceiver.ACTION_ALARM);

        final PendingIntent pIntent = PendingIntent.getBroadcast(this, 1234567,
                intent, PendingIntent.FLAG_UPDATE_CURRENT);

        AlarmManager alarms = (AlarmManager) this
                .getSystemService(Context.ALARM_SERVICE);

        alarms.cancel(pIntent);
        toast("Canceled...");
    }

    public void toast(String message) {
        Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT)
                .show();
    }

Android マニフェスト

INTERNET権限取得

        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

   <service android:name=".TaskService" >
</service>

<receiver
    android:name="AlaramReceiver"
    android:process=":remote" >
</receiver>

4

1 に答える 1

1

問題は、IntentService から表示されるトースト メッセージにあります。修正は簡単です。サービスの onCreate で Handler を作成し、Runnable を投稿してトーストを表示します。

public class TaskService extends IntentService {
...
    private Handler mHandler;

    protected void onCreate() {
        mHandler = new Handler();
    }

    ...

    public boolean uploadRecording(... {
    ...
        mHandler.post(new Runnable() {
            public void run() {
                Toast.makeText(getApplicationContext(), "Upload Success", Toast.LENGTH_SHORT).show();
            }
        });
    ...
    }

}

内部的に、toast は Handler を使用して INotificationManager と通信します。トーストが作成されると、作成されたスレッドのルーパーを使用する Handler のインスタンスが作成されます。あなたの場合は IntentService の HandlerThread です。サービスがすべての作業を終了すると中断されます。それが死んでいる理由です。

于 2014-09-05T16:23:18.883 に答える