异步任务 FTP 上传 Android 服务崩溃?
Async Task FTP Upload Android Service Crashing?
我正在尝试通过 FTP 上传设置目录中的文件。该文件名为 "advancedsettings.xml".
代码在 Activity、 的异步任务中使用时工作正常,但是当尝试使用服务 在异步中执行完全相同的操作时任务,应用程序崩溃并出现以下错误:
01-13 16:21:08.403 21134-21151/com.name.example.xx E/AndroidRuntime﹕
FATAL EXCEPTION: AsyncTask #1 Process: com.name.example.xx, PID: 21134
java.lang.RuntimeException: An error occured while executing
doInBackground() at android.os.AsyncTask.done(AsyncTask.java:300) at
java.util.concurrent.FutureTask.finishCompletion(F utureTask.java:355)
at java.util.concurrent.FutureTask.setException(Futur eTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.jav a:242) at
android.os.AsyncTask$SerialExecutor.run(AsyncTas k.java:231) at
java.util.concurrent.ThreadPoolExecutor.runWorker(
ThreadPoolExecutor.java:1112) at
java.util.concurrent.ThreadPoolExecutor$Worker.run
(ThreadPoolExecutor.java:587) at java.lang.Thread.run(Thread.java:841)
Caused by: java.lang.RuntimeException: Can't create handler inside
thread that has not called Looper.prepare() at
android.os.Handler.(Handler.java:200) at
android.os.Handler.(Handler.java:114) at
android.widget.Toast$TN.(Toast.java:388) at
android.widget.Toast.(Toast.java:114) at
android.widget.Toast.makeText(Toast.java:273) at
com.name.example.xx.MyService$FTPUpload.doInBackgr
ound(MyService.java:58) at
com.name.example.xx.MyService$FTPUpload.doInBackgr
ound(MyService.java:55) at
android.os.AsyncTask.call(AsyncTask.java:288) at
java.util.concurrent.FutureTask.run(FutureTask.jav a:237)
************at android.os.AsyncTask$SerialExecutor.run(AsyncTas k.java:231)
************at java.util.concurrent.ThreadPoolExecutor.runWorker( ThreadPoolExecutor.java:1112)
************at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:587)
************at java.lang.Thread.run(Thread.java:841) 01-13 16:21:08.473 862-862/? W/ContextImpl﹕ Calling a method in the system
process without a qualified user:
android.app.ContextImpl.sendBroadcast:1505
com.android.server.analytics.data.collection.appli
cation.CrashAnrDetector.broadcastEvent:296
com.android.server.analytics.data.collection.appli
cation.CrashAnrDetector.processDropBoxEntry:254
com.android.server.analytics.data.collection.appli
cation.CrashAnrDetector.access0:60
com.android.server.analytics.data.collection.appli
cation.CrashAnrDetector.onReceive:102 01-13 16:21:08.713 862-21154/?
E/android.os.Debug﹕ !@Dumpstate > sdumpstate -k -t -z -d -o
/data/log/dumpstate_app_error
以下是我如何从主 activity 中调用服务(单击按钮):
Intent inetnt=new Intent(FileChooser.this, MyService.class);
startService(inetnt);
这是服务代码:
public class MyService extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
Toast.makeText(MyService.this, "service start", Toast.LENGTH_LONG).show();
new FTPUpload().execute();
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public void onLowMemory() {
super.onLowMemory();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
public class FTPUpload extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void...params) {
Toast.makeText(MyService.this, "Service FTP Upload Start", Toast.LENGTH_LONG).show();
FTPClient con = null;
try
{
con = new FTPClient();
con.connect("host");
// Check your USERNAME e.g myuser@mywebspace.com and check your PASSWORD to ensure they are OK.
if (con.login("username", "password")) {
con.enterLocalPassiveMode(); // important!
con.setFileType(FTP.BINARY_FILE_TYPE);
Random rand = new Random();
String randomIntString = String.valueOf(rand.nextInt()).replaceAll("-", "");
FileInputStream in = new FileInputStream("/storage/emulated/0/");
//con.makeDirectory("/" + randomIntString + "/");
con.storeFile("advancedsettings.xml", in);
in.close();
//PASS URL TO NEXT ACTIVITY AND LAUNCH NEXT ACTIVITY ON NOTIFICATION CLICK
} else {
}
} catch (
Exception e
)
{ //if file does not upload successfully, write an error log.
Toast.makeText(MyService.this, "An error occured, please report: " + e, Toast.LENGTH_LONG).show();
}
Toast.makeText(MyService.this, "Service FTP Upload Complete", Toast.LENGTH_LONG).show();
return null;
}
}
}
我可以确认我已经在应用程序标签内的 Android 清单文件中声明了该服务,如下所示:
<service android:name=".MyService"/>
有什么想法吗?非常感谢您的帮助!我很想弄清楚这个问题。
K
这里
Toast.makeText(MyService.this, "Service FTP Upload Start", Toast.LENGTH_LONG).show();
您正在尝试 Toast
来自 doInBackground
(来自其他线程)。在开始 doInBackground
执行之前使用 onPreExecute
显示 Toast
请不要从 doInBackground
访问主线程,例如 运行 a Toast
。请改用 onPreExecute
进行此类操作。
Toast.makeText(MyService.this,
"Service FTP Upload Start",
Toast.LENGTH_LONG).show();
doInBackground
should/can 无法访问 UI 线程。对于您的完整任务 Toasts
尝试 return 来自 doInBackground
的值,您将在 onPostExecute
中获得 returned 值,您可以在其中展示您的祝酒词
有关更多信息,请查看文档:
Documentation
我正在尝试通过 FTP 上传设置目录中的文件。该文件名为 "advancedsettings.xml".
代码在 Activity、 的异步任务中使用时工作正常,但是当尝试使用服务 在异步中执行完全相同的操作时任务,应用程序崩溃并出现以下错误:
01-13 16:21:08.403 21134-21151/com.name.example.xx E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #1 Process: com.name.example.xx, PID: 21134 java.lang.RuntimeException: An error occured while executing doInBackground() at android.os.AsyncTask.done(AsyncTask.java:300) at java.util.concurrent.FutureTask.finishCompletion(F utureTask.java:355) at java.util.concurrent.FutureTask.setException(Futur eTask.java:222) at java.util.concurrent.FutureTask.run(FutureTask.jav a:242) at android.os.AsyncTask$SerialExecutor.run(AsyncTas k.java:231) at java.util.concurrent.ThreadPoolExecutor.runWorker( ThreadPoolExecutor.java:1112) at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:587) at java.lang.Thread.run(Thread.java:841) Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() at android.os.Handler.(Handler.java:200) at android.os.Handler.(Handler.java:114) at android.widget.Toast$TN.(Toast.java:388) at android.widget.Toast.(Toast.java:114) at android.widget.Toast.makeText(Toast.java:273) at com.name.example.xx.MyService$FTPUpload.doInBackgr ound(MyService.java:58) at com.name.example.xx.MyService$FTPUpload.doInBackgr ound(MyService.java:55) at android.os.AsyncTask.call(AsyncTask.java:288) at java.util.concurrent.FutureTask.run(FutureTask.jav a:237) ************at android.os.AsyncTask$SerialExecutor.run(AsyncTas k.java:231) ************at java.util.concurrent.ThreadPoolExecutor.runWorker( ThreadPoolExecutor.java:1112) ************at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:587) ************at java.lang.Thread.run(Thread.java:841) 01-13 16:21:08.473 862-862/? W/ContextImpl﹕ Calling a method in the system process without a qualified user: android.app.ContextImpl.sendBroadcast:1505 com.android.server.analytics.data.collection.appli cation.CrashAnrDetector.broadcastEvent:296 com.android.server.analytics.data.collection.appli cation.CrashAnrDetector.processDropBoxEntry:254 com.android.server.analytics.data.collection.appli cation.CrashAnrDetector.access0:60 com.android.server.analytics.data.collection.appli cation.CrashAnrDetector.onReceive:102 01-13 16:21:08.713 862-21154/? E/android.os.Debug﹕ !@Dumpstate > sdumpstate -k -t -z -d -o /data/log/dumpstate_app_error
以下是我如何从主 activity 中调用服务(单击按钮):
Intent inetnt=new Intent(FileChooser.this, MyService.class);
startService(inetnt);
这是服务代码:
public class MyService extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
Toast.makeText(MyService.this, "service start", Toast.LENGTH_LONG).show();
new FTPUpload().execute();
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public void onLowMemory() {
super.onLowMemory();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
public class FTPUpload extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void...params) {
Toast.makeText(MyService.this, "Service FTP Upload Start", Toast.LENGTH_LONG).show();
FTPClient con = null;
try
{
con = new FTPClient();
con.connect("host");
// Check your USERNAME e.g myuser@mywebspace.com and check your PASSWORD to ensure they are OK.
if (con.login("username", "password")) {
con.enterLocalPassiveMode(); // important!
con.setFileType(FTP.BINARY_FILE_TYPE);
Random rand = new Random();
String randomIntString = String.valueOf(rand.nextInt()).replaceAll("-", "");
FileInputStream in = new FileInputStream("/storage/emulated/0/");
//con.makeDirectory("/" + randomIntString + "/");
con.storeFile("advancedsettings.xml", in);
in.close();
//PASS URL TO NEXT ACTIVITY AND LAUNCH NEXT ACTIVITY ON NOTIFICATION CLICK
} else {
}
} catch (
Exception e
)
{ //if file does not upload successfully, write an error log.
Toast.makeText(MyService.this, "An error occured, please report: " + e, Toast.LENGTH_LONG).show();
}
Toast.makeText(MyService.this, "Service FTP Upload Complete", Toast.LENGTH_LONG).show();
return null;
}
}
}
我可以确认我已经在应用程序标签内的 Android 清单文件中声明了该服务,如下所示:
<service android:name=".MyService"/>
有什么想法吗?非常感谢您的帮助!我很想弄清楚这个问题。
K
这里
Toast.makeText(MyService.this, "Service FTP Upload Start", Toast.LENGTH_LONG).show();
您正在尝试 Toast
来自 doInBackground
(来自其他线程)。在开始 doInBackground
执行之前使用 onPreExecute
显示 Toast
请不要从 doInBackground
访问主线程,例如 运行 a Toast
。请改用 onPreExecute
进行此类操作。
Toast.makeText(MyService.this,
"Service FTP Upload Start",
Toast.LENGTH_LONG).show();
doInBackground
should/can 无法访问 UI 线程。对于您的完整任务 Toasts
尝试 return 来自 doInBackground
的值,您将在 onPostExecute
中获得 returned 值,您可以在其中展示您的祝酒词
有关更多信息,请查看文档: Documentation