我目前正在使用AlarmManager,广播接收器和Intent Service来实现上传服务到后台服务器而不是Ui主线程,但问题是当执行时,上传消息没有响应。至少,在logcat中,我可以看到任何消息,报告我已正确输入和测试的上传进度。
但是上传服务完成后会显示出来 java.lang.RuntimeException:Handler(android.os.Handler)在死线程上向Handler发送消息
你能告诉我还缺少什么吗?以下是我的代码
Intnt Service
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;
}
}
BroadCast接收器
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 Manifest
获得INTERNET Permisson
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".TaskService" >
</service>
<receiver
android:name="AlaramReceiver"
android:process=":remote" >
</receiver>
答案 0 :(得分:1)
您的问题出在IntentService显示的Toast消息中。 修复很简单:在服务的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进行通信。一旦创建了toast,就会创建Handler的实例,它使用来自创建它的线程的looper。在你的情况下,它是IntentService的HandlerThread。一旦服务完成所有工作,它就会中断。这就是为什么它已经死了。