Android Dropbox V2 NetworkOnMainThreadException
Android Dropbox V2 NetworkOnMainThreadException
一段时间以来,我一直在努力让 Dropbox V2 与我的应用程序一起工作,但我不确定我还能做些什么。我基本上遵循了在线教程和其他资源,但我不断收到错误,使我无法继续前进。奇怪的是,当我第一次输入新代码时,它运行良好。一旦我开始添加确认上传成功或其他任何东西的警报,它就会在尝试登录时开始出现故障。我感觉该应用程序仍通过旧代码登录,但我无法确认这一点,因为我没有保存当时项目的副本。我试过将代码放在单独的线程中,但仍然出现错误。好像它没有像应该的那样连接到 API,但我不知道我在这里做错了什么。我正在为令牌放置应用程序密钥,这意味着有所不同吗?
这是我的代码:
try {
DbxRequestConfig config = new DbxRequestConfig("dropbox/java-tutorial");
client = new DbxClientV2(config, "token");
// Get current account info
FullAccount account = client.users().getCurrentAccount();
System.out.println(account.getName().getDisplayName());
// Get files and folder metadata from Dropbox root directory
ListFolderResult result = client.files().listFolder("");
while (true) {
for (Metadata metadata : result.getEntries()) {
System.out.println(metadata.getPathLower());
}
if (!result.getHasMore()) {
break;
}
result = client.files().listFolderContinue(result.getCursor());
}
} catch(DbxException e){}
以及文件上传代码:
Thread t = new Thread(new Runnable() {
@Override
public void run() {
Exception mException=null;
FileMetadata metadata=null;
try {
// Upload "test.txt" to Dropbox
//dialog.dismiss();
metadata = client.files().uploadBuilder("/"+title+".sheet").uploadAndFinish(fis);
} catch(DbxException e){
mException = e;
}
catch(IOException e){
mException = e;
}
if (mException != null) {
//dialog.dismiss();
final Exception finalE = mException;
Handler h = new Handler(Looper.getMainLooper());
h.post(new Runnable() {
public void run() {
Log.e(TAG, "Failed to upload file.", finalE);
Toast.makeText(MainActivity.this,
"An error has occurred",
Toast.LENGTH_SHORT)
.show();
}
});
} else if (metadata == null) {
//dialog.dismiss();
final Exception finalE = mException;
Handler h = new Handler(Looper.getMainLooper());
h.post(new Runnable() {
public void run() {
Log.e(TAG, "Failed to upload file.", finalE);
Toast.makeText(MainActivity.this,
"An error has occurred",
Toast.LENGTH_SHORT)
.show();
}
});
} else {
//dialog.dismiss();
final String message = metadata.getName() + " size " + metadata.getSize() + " modified " +
DateFormat.getDateTimeInstance().format(metadata.getClientModified());
Handler h = new Handler(Looper.getMainLooper());
h.post(new Runnable() {
public void run() {
Toast.makeText(MainActivity.this,
message,
Toast.LENGTH_SHORT)
.show();
}
});
}
}
});
t.start();
如有任何想法或提示,我们将不胜感激。
最终通过异步任务解决了这个问题。我也未能获得 Auth 令牌,而是愚蠢地使用我的密钥。
异步任务:
import android.content.Context;
import android.os.AsyncTask;
import com.dropbox.core.DbxException;
import com.dropbox.core.v2.DbxClientV2;
import com.dropbox.core.DbxRequestConfig;
import com.dropbox.core.v2.users.FullAccount;
public class ConnectToDB extends AsyncTask<String, Void, FullAccount> {
private final Context mContext;
private DbxClientV2 mDbxClient;
private Exception mException;
private String token;
private Callback mCallback;
public interface Callback {
void onLoginComplete(FullAccount result, DbxClientV2 client);
void onError(Exception e);
}
ConnectToDB(Context context, String token, Callback callback) {
mContext = context;
this.token=token;
mCallback=callback;
}
@Override
protected void onPostExecute(FullAccount result) {
super.onPostExecute(result);
if (mException != null) {
mCallback.onError(mException);
} else if (result == null) {
mCallback.onError(null);
} else {
mCallback.onLoginComplete(result, mDbxClient);
}
}
@Override
protected FullAccount doInBackground(String... params) {
DbxRequestConfig config = new DbxRequestConfig("appName");
mDbxClient = new DbxClientV2(config, this.token);
try {
// Get current account info
return mDbxClient.users().getCurrentAccount();
}catch (DbxException e){
mException = e;
}
return null;
}
}
token的正确获取方式
public void initDropBox(){
if (prefs.getString("dbKey", "").equals("")) {
Auth.startOAuth2Authentication(this,"appKey");
prefs.edit().putString("dbKey", Auth.getOAuth2Token()).commit();
}else{
initAndLoadData(prefs.getString("dbKey", ""));
}
}
@Override
protected void onResume()
{
super.onResume();
try{
String accessToken = prefs.getString("dbKey",null);
if (accessToken == null) {
accessToken = Auth.getOAuth2Token();
if (accessToken != null) {
prefs.edit().putString("dbKey", accessToken).apply();
initAndLoadData(accessToken);
}
}else{
initAndLoadData(accessToken);
}
}catch(Exception e){}
}
private void initAndLoadData(String accessToken) {
final MainActivity context = this;
new ConnectToDB(this, accessToken, new ConnectToDB.Callback() {
@Override
public void onLoginComplete(FullAccount result, DbxClientV2 client) {
context.client = client;
Log.e(TAG, "Success.", null);
}
@Override
public void onError(Exception e) {
Log.e(TAG, "Failed to login.", e);
Toast.makeText(MainActivity.this,
"An error has occurred",
Toast.LENGTH_SHORT)
.show();
}
}).execute();
}
一段时间以来,我一直在努力让 Dropbox V2 与我的应用程序一起工作,但我不确定我还能做些什么。我基本上遵循了在线教程和其他资源,但我不断收到错误,使我无法继续前进。奇怪的是,当我第一次输入新代码时,它运行良好。一旦我开始添加确认上传成功或其他任何东西的警报,它就会在尝试登录时开始出现故障。我感觉该应用程序仍通过旧代码登录,但我无法确认这一点,因为我没有保存当时项目的副本。我试过将代码放在单独的线程中,但仍然出现错误。好像它没有像应该的那样连接到 API,但我不知道我在这里做错了什么。我正在为令牌放置应用程序密钥,这意味着有所不同吗? 这是我的代码:
try {
DbxRequestConfig config = new DbxRequestConfig("dropbox/java-tutorial");
client = new DbxClientV2(config, "token");
// Get current account info
FullAccount account = client.users().getCurrentAccount();
System.out.println(account.getName().getDisplayName());
// Get files and folder metadata from Dropbox root directory
ListFolderResult result = client.files().listFolder("");
while (true) {
for (Metadata metadata : result.getEntries()) {
System.out.println(metadata.getPathLower());
}
if (!result.getHasMore()) {
break;
}
result = client.files().listFolderContinue(result.getCursor());
}
} catch(DbxException e){}
以及文件上传代码:
Thread t = new Thread(new Runnable() {
@Override
public void run() {
Exception mException=null;
FileMetadata metadata=null;
try {
// Upload "test.txt" to Dropbox
//dialog.dismiss();
metadata = client.files().uploadBuilder("/"+title+".sheet").uploadAndFinish(fis);
} catch(DbxException e){
mException = e;
}
catch(IOException e){
mException = e;
}
if (mException != null) {
//dialog.dismiss();
final Exception finalE = mException;
Handler h = new Handler(Looper.getMainLooper());
h.post(new Runnable() {
public void run() {
Log.e(TAG, "Failed to upload file.", finalE);
Toast.makeText(MainActivity.this,
"An error has occurred",
Toast.LENGTH_SHORT)
.show();
}
});
} else if (metadata == null) {
//dialog.dismiss();
final Exception finalE = mException;
Handler h = new Handler(Looper.getMainLooper());
h.post(new Runnable() {
public void run() {
Log.e(TAG, "Failed to upload file.", finalE);
Toast.makeText(MainActivity.this,
"An error has occurred",
Toast.LENGTH_SHORT)
.show();
}
});
} else {
//dialog.dismiss();
final String message = metadata.getName() + " size " + metadata.getSize() + " modified " +
DateFormat.getDateTimeInstance().format(metadata.getClientModified());
Handler h = new Handler(Looper.getMainLooper());
h.post(new Runnable() {
public void run() {
Toast.makeText(MainActivity.this,
message,
Toast.LENGTH_SHORT)
.show();
}
});
}
}
});
t.start();
如有任何想法或提示,我们将不胜感激。
最终通过异步任务解决了这个问题。我也未能获得 Auth 令牌,而是愚蠢地使用我的密钥。
异步任务:
import android.content.Context;
import android.os.AsyncTask;
import com.dropbox.core.DbxException;
import com.dropbox.core.v2.DbxClientV2;
import com.dropbox.core.DbxRequestConfig;
import com.dropbox.core.v2.users.FullAccount;
public class ConnectToDB extends AsyncTask<String, Void, FullAccount> {
private final Context mContext;
private DbxClientV2 mDbxClient;
private Exception mException;
private String token;
private Callback mCallback;
public interface Callback {
void onLoginComplete(FullAccount result, DbxClientV2 client);
void onError(Exception e);
}
ConnectToDB(Context context, String token, Callback callback) {
mContext = context;
this.token=token;
mCallback=callback;
}
@Override
protected void onPostExecute(FullAccount result) {
super.onPostExecute(result);
if (mException != null) {
mCallback.onError(mException);
} else if (result == null) {
mCallback.onError(null);
} else {
mCallback.onLoginComplete(result, mDbxClient);
}
}
@Override
protected FullAccount doInBackground(String... params) {
DbxRequestConfig config = new DbxRequestConfig("appName");
mDbxClient = new DbxClientV2(config, this.token);
try {
// Get current account info
return mDbxClient.users().getCurrentAccount();
}catch (DbxException e){
mException = e;
}
return null;
}
}
token的正确获取方式
public void initDropBox(){
if (prefs.getString("dbKey", "").equals("")) {
Auth.startOAuth2Authentication(this,"appKey");
prefs.edit().putString("dbKey", Auth.getOAuth2Token()).commit();
}else{
initAndLoadData(prefs.getString("dbKey", ""));
}
}
@Override
protected void onResume()
{
super.onResume();
try{
String accessToken = prefs.getString("dbKey",null);
if (accessToken == null) {
accessToken = Auth.getOAuth2Token();
if (accessToken != null) {
prefs.edit().putString("dbKey", accessToken).apply();
initAndLoadData(accessToken);
}
}else{
initAndLoadData(accessToken);
}
}catch(Exception e){}
}
private void initAndLoadData(String accessToken) {
final MainActivity context = this;
new ConnectToDB(this, accessToken, new ConnectToDB.Callback() {
@Override
public void onLoginComplete(FullAccount result, DbxClientV2 client) {
context.client = client;
Log.e(TAG, "Success.", null);
}
@Override
public void onError(Exception e) {
Log.e(TAG, "Failed to login.", e);
Toast.makeText(MainActivity.this,
"An error has occurred",
Toast.LENGTH_SHORT)
.show();
}
}).execute();
}