オンラインAPIにアクセスする必要があるMainActivity
クラスがあります(したがって、ネットワークリソースを使用します)。これには、別のファイルで作成したバックグラウンドスレッドが必要ですHttpRequestService.Java
。
public class MainActivity extends Activity {
public static final String API_KEY = "KEYKEYKEYKEYKEY";
public static final String CLIENT_ID = "IDIDIDIDIDIDID";
private final String BROADCAST_ACTION = "com.example.BROADCAST";
private final String EXTENDED_DATA_STATUS = "com.example.STATUS";
static final String LOGCAT_TAG = "TAGTAGTAGTAGTAG";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
protected void onResume() {
super.onResume();
String token = "TOKENTOKENTOKENTOKEN";
String urlString = "https://www.example.com/api?key=" + API_KEY;
// Create and start intent for HttpRequestService background thread.
Intent httpRequestServiceIntent = new Intent(this, HttpRequestService.class);
httpRequestServiceIntent.putExtra("token", token);
httpRequestServiceIntent.putExtra("urlString", urlString);
httpRequestServiceIntent.putExtra("client_id", CLIENT_ID);
DownloadStateReceiver downloadStateReceiver = new DownloadStateReceiver();
LocalBroadcastManager.getInstance(this).registerReceiver(downloadStateReceiver, new IntentFilter(BROADCAST_ACTION));
this.startService(httpRequestServiceIntent);
}
private class DownloadStateReceiver extends BroadcastReceiver {
// Broadcast receiver for receiving status updates from IntentService
private DownloadStateReceiver() {
// prevents instantiation
}
@Override
public void onReceive(Context context, Intent intent) {
String message = intent.getStringExtra(EXTENDED_DATA_STATUS);
Log.d(LOGCAT_TAG, "onReceive received message: " + message);
Toast.makeText(context, "Success!: " + message, Toast.LENGTH_LONG).show();
}
}
public final class HttpRequestService extends IntentService {
public HttpRequestService(String name) {
super(name);
Log.e(LOGCAT_TAG, "You called the HttpRequestService directly. Don't do that. Call onHandleIntent.");
}
private final String LOGCAT_TAG = "HttpRequestService";
private final String BROADCAST_ACTION = "com.genda.dayplanner.BROADCAST";
private final String EXTENDED_DATA_STATUS = "com.genda.dayplanner.STATUS";
@Override
protected void onHandleIntent(Intent intent) {
// Gets data from the incoming Intent
String token = intent.getStringExtra("token");
String urlString = intent.getStringExtra("urlString");
String client_id = intent.getStringExtra("client_id");
Boolean extraError = false;
if (token == null) {
Log.e(LOGCAT_TAG, "Intent didn't contain required token.");
extraError = true;
}
if (urlString == null) {
Log.e(LOGCAT_TAG, "Intent didn't contain required urlBundle.");
extraError = true;
}
if (client_id == null) {
Log.e(LOGCAT_TAG, "Intent didn't contain required client_id.");
extraError = true;
}
if (extraError == true) {
// error response
}
// Now do request
URL url = null;
try {
url = new URL(urlString);
} catch (MalformedURLException e) {
Log.e(LOGCAT_TAG, "The URL for requesting the tasks API was malformed.");
}
HttpURLConnection conn = null;
try {
conn = (HttpURLConnection) url.openConnection();
} catch (IOException e) {
Log.e(LOGCAT_TAG, "Bad connection to the API URL");
}
conn.addRequestProperty("client_id", client_id);
conn.setRequestProperty("Authorization", "OAuth " + token);
String result = null;
try {
InputStream in = new BufferedInputStream(conn.getInputStream());
result = convertStreamToString(in);
} catch (IOException e) {
e.printStackTrace();
} finally {
conn.disconnect();
}
// Create new Intent with URI object
Intent localIntent = new Intent(BROADCAST_ACTION);
localIntent.putExtra(EXTENDED_DATA_STATUS, result);
// Broadcasts intent to receivers in this app.
LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent);
}
public static String convertStreamToString(InputStream in) {
// Use BufferedReader.readLine() method. Iterate until BufferedReader returns null (no more data to read). Each line appended to StringBuilder.
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
}
09-21 17:15:28.157: D/dalvikvm(11055): newInstance failed: no <init>()
09-21 17:15:28.157: D/AndroidRuntime(11055): Shutting down VM
09-21 17:15:28.157: W/dalvikvm(11055): threadid=1: thread exiting with uncaught exception (group=0x41f3b700)
09-21 17:15:28.167: E/AndroidRuntime(11055): FATAL EXCEPTION: main
09-21 17:15:28.167: E/AndroidRuntime(11055): Java.lang.RuntimeException: Unable to instantiate service com.example.HttpRequestService: Java.lang.InstantiationException: can't instantiate class com.example.HttpRequestService; no empty constructor
09-21 17:15:28.167: E/AndroidRuntime(11055): at Android.app.ActivityThread.handleCreateService(ActivityThread.Java:2561)
09-21 17:15:28.167: E/AndroidRuntime(11055): at Android.app.ActivityThread.access$1600(ActivityThread.Java:141)
09-21 17:15:28.167: E/AndroidRuntime(11055): at Android.app.ActivityThread$H.handleMessage(ActivityThread.Java:1338)
09-21 17:15:28.167: E/AndroidRuntime(11055): at Android.os.Handler.dispatchMessage(Handler.Java:99)
09-21 17:15:28.167: E/AndroidRuntime(11055): at Android.os.Looper.loop(Looper.Java:137)
09-21 17:15:28.167: E/AndroidRuntime(11055): at Android.app.ActivityThread.main(ActivityThread.Java:5103)
09-21 17:15:28.167: E/AndroidRuntime(11055): at Java.lang.reflect.Method.invokeNative(Native Method)
09-21 17:15:28.167: E/AndroidRuntime(11055): at Java.lang.reflect.Method.invoke(Method.Java:525)
09-21 17:15:28.167: E/AndroidRuntime(11055): at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:737)
09-21 17:15:28.167: E/AndroidRuntime(11055): at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:553)
09-21 17:15:28.167: E/AndroidRuntime(11055): at dalvik.system.NativeStart.main(Native Method)
09-21 17:15:28.167: E/AndroidRuntime(11055): Caused by: Java.lang.InstantiationException: can't instantiate class com.example.HttpRequestService; no empty constructor
09-21 17:15:28.167: E/AndroidRuntime(11055): at Java.lang.Class.newInstanceImpl(Native Method)
09-21 17:15:28.167: E/AndroidRuntime(11055): at Java.lang.Class.newInstance(Class.Java:1130)
09-21 17:15:28.167: E/AndroidRuntime(11055): at Android.app.ActivityThread.handleCreateService(ActivityThread.Java:2558)
09-21 17:15:28.167: E/AndroidRuntime(11055): ... 10 more
私が考える重要な部分はcan't instantiate class com.example.HttpRequestService; no empty constructor
。これに似た他の議論もいくつか見ましたが、クラスはMainActivityのサブクラスであるため、全員が問題を解決できます。したがって、サブクラスを静的にし、問題を解決します。残念ながら、別のクラスとしてHttpRequestService
を静的にすることはできません。助言がありますか?
Exception
は、デフォルトのパブリックコンストラクターを実装する必要があることを示しています。
_ public HttpRequestService() {
super("Name for Service");
}
_
デフォルトのパブリックコンストラクターはパラメーターのないコンストラクターです。
ここでsuper()
を呼び出し、String
に名前を付けるために使用されるIntentService
を渡します。
留意すべきもう1つの点があります。サービスをネストされたクラスとして使用する場合は、静的である必要があります。