Issue
I read a few tutorials (one at tutorial point, and one at developer.android.com) and thought I was doing this correctly to avoid having this error android.os.NetworkOnMainThreadException However, I am still getting it despite having my network connection in the service started by calling startService (which happens when I click the start button in mainactivity, I didn't add the layout xml, but the onClick method has been set)
I will try to paste relevant code here:
main activity
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void startService(View view) {
startService(new Intent(getBaseContext(),MyService.class));
}
public void stopService(View view) {
stopService(new Intent(getBaseContext(), MyService.class));
}
}
Service
public class MyService extends Service {
@Override
public IBinder onBind(Intent arg0) {
return null;
}
/*@Override
public void onCreate() {
}*/
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "Service Started", Toast.LENGTH_SHORT).show();
KClient client = new KClient(8096);
if(client.openConn("login","password")) {
Toast.makeText(this,"Connected",Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this,"failed to connect",Toast.LENGTH_SHORT).show();
}
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
}
}
manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.frizzled.MyService">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".MyService" />
</application>
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
Solution
onStartCommand() is called on the main application thread. A Service does not have any threads of its own. Certain specific subclasses of Service, like IntentService, do. Whether you should use IntentService, or whether you should continue using Service but fork your own thread, would depend a lot on what you are planning on doing with the network connection:
if the work will be fairly transactional (open the connection, do some work, close the connection, go away), use
IntentService, with your networking work inonHandleIntent()if the work will more open-ended in terms of timing, like a chat client, use your own thread (managed by a
Serviceor not, depending on whether you need other features of theService, such as process importance)
Answered By - CommonsWare
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.