kalz
kalz

Reputation: 173

How to start an android web server service?

I have a WebServerService which I would like to start when a toggle button is pressed. The same button also launches a dialog and notifies the user.

I have tried the following code from my main activity:

startService(new Intent(MyActivity.this, WebServerService.class));

But the application UI freezes and the dialog doesn't show up and the application force closes. The code for the WebServerService class is:

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

public class WebServerService extends Service { 
    private WebServer server = null;

    @Override
    public void onCreate() {
        Log.i("HTTPSERVICE", "Creating and starting httpService");
        super.onCreate();
        server = new WebServer(this);
        server.startServer();   
    }

    @Override
    public void onDestroy() {
        Log.i("HTTPSERVICE", "Destroying httpService");
        server.stopServer();
        super.onDestroy();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

I have been trying hard to get this to work. I have also looked at AsyncTask but I'm not sure if that is applicable in my case. Any help or a pointer in the right direction would be greatly appreciated.

The WebServer class is as follows:

package com.xlnc.webapp;  
import java.io.IOException;  
import java.net.ServerSocket;  
import java.net.Socket;  
import java.net.SocketException;  

import org.apache.http.HttpException;
import org.apache.http.impl.DefaultConnectionReuseStrategy;
import org.apache.http.impl.DefaultHttpResponseFactory;
import org.apache.http.impl.DefaultHttpServerConnection;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.BasicHttpProcessor;
import org.apache.http.protocol.HttpRequestHandlerRegistry;
import org.apache.http.protocol.HttpService;
import org.apache.http.protocol.ResponseConnControl;
import org.apache.http.protocol.ResponseContent;
import org.apache.http.protocol.ResponseDate;
import org.apache.http.protocol.ResponseServer;

import android.content.Context;

public class WebServer {

public static boolean RUNNING = false;
public static int serverPort = 8080;

private static final String ALL_PATTERN = "*";
private static final String EXCEL_PATTERN = "/*.xls";
private static final String HOME_PATTERN = "/home.html";

private Context context = null;

private BasicHttpProcessor httpproc = null;
private BasicHttpContext httpContext = null;
private HttpService httpService = null;
private HttpRequestHandlerRegistry registry = null;

public WebServer(Context context) {
    this.setContext(context);

    httpproc = new BasicHttpProcessor();
    httpContext = new BasicHttpContext();

    httpproc.addInterceptor(new ResponseDate());
    httpproc.addInterceptor(new ResponseServer());
    httpproc.addInterceptor(new ResponseContent());
    httpproc.addInterceptor(new ResponseConnControl());

    httpService = new HttpService(httpproc,
        new DefaultConnectionReuseStrategy(), new DefaultHttpResponseFactory());

    registry = new HttpRequestHandlerRegistry();

    registry.register(HOME_PATTERN, new HomeCommandHandler(context));

    httpService.setHandlerResolver(registry);
}

private ServerSocket serverSocket;

public void runServer() {
    try {
        serverSocket = new ServerSocket(serverPort);

        serverSocket.setReuseAddress(true);

        while (RUNNING) {
            try {
                final Socket socket = serverSocket.accept();

                DefaultHttpServerConnection serverConnection = new DefaultHttpServerConnection();

                serverConnection.bind(socket, new BasicHttpParams());

                httpService.handleRequest(serverConnection, httpContext);

                serverConnection.shutdown();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (HttpException e) {
                e.printStackTrace();
            }
        }

        serverSocket.close();
    } catch (SocketException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    RUNNING = false;
}

public synchronized void startServer() {
    RUNNING = true;
    runServer();
}

public synchronized void stopServer() {
    RUNNING = false;
    if (serverSocket != null) {
        try {
            serverSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

public void setContext(Context context) {
    this.context = context;
}

public Context getContext() {
    return context;
}
}


Edit: Here are logs:

08-01 22:55:04.406: I/PackageManager(65): /data/app/vmdl40565.tmp changed; unpacking
08-01 22:55:04.550: D/installd(31): DexInv: --- BEGIN '/data/app/vmdl40565.tmp' ---
08-01 22:55:04.637: D/dalvikvm(143): GC freed 2787 objects / 185600 bytes in 239ms
08-01 22:55:05.226: D/dalvikvm(205): DexOpt: load 39ms, verify 132ms, opt 1ms
08-01 22:55:05.236: D/installd(31): DexInv: --- END '/data/app/vmdl40565.tmp' (success) ---
08-01 22:55:05.526: I/installd(31): move /data/dalvik-cache/data@[email protected]@classes.dex -> /data/dalvik-cache/data@[email protected]@classes.dex
08-01 22:55:05.526: D/PackageManager(65): New package installed in /data/app/com.xlnc.webapp.apk
08-01 22:55:05.696: D/MountListener(65): handleEvent ums_disabled
08-01 22:55:05.756: D/MountListener(65): handleEvent ums_disconnected
08-01 22:55:05.766: D/AndroidRuntime(162): Shutting down VM
08-01 22:55:05.766: D/dalvikvm(162): DestroyJavaVM waiting for non-daemon threads to exit
08-01 22:55:05.766: D/dalvikvm(162): DestroyJavaVM shutting VM down
08-01 22:55:05.776: D/dalvikvm(162): HeapWorker thread shutting down
08-01 22:55:05.776: D/dalvikvm(162): HeapWorker thread has shut down
08-01 22:55:05.776: D/jdwp(162): JDWP shutting down net...
08-01 22:55:05.776: I/jdwp(162): adbd disconnected
08-01 22:55:05.789: D/dalvikvm(162): VM cleaning up
08-01 22:55:05.826: E/AndroidRuntime(162): ERROR: thread attach failed
08-01 22:55:05.826: D/dalvikvm(162): LinearAlloc 0x0 used 621708 of 5242880 (11%)
08-01 22:55:06.396: D/dalvikvm(65): GC freed 4364 objects / 319160 bytes in 245ms
08-01 22:55:06.596: D/MediaScannerService(179): start scanning volume internal
08-01 22:55:06.716: I/ActivityManager(65): Start proc com.android.mms for broadcast com.android.mms/.transaction.MmsSystemEventReceiver: pid=212 uid=10014 gids={3003, 1015}
08-01 22:55:07.306: D/installd(31): DexInv: --- BEGIN '/system/app/Mms.apk' ---
08-01 22:55:07.476: D/AndroidRuntime(210): >>>>>>>>>>>>>> AndroidRuntime START <<<<<<<<<<<<<<
08-01 22:55:07.496: W/ResourceType(65): Resources don't contain package for resource number 0x7f0700e5
08-01 22:55:07.496: D/AndroidRuntime(210): CheckJNI is ON
08-01 22:55:07.508: W/ResourceType(65): Resources don't contain package for resource number 0x7f020031
08-01 22:55:07.508: W/ResourceType(65): Resources don't contain package for resource number 0x7f020030
08-01 22:55:07.508: W/ResourceType(65): Resources don't contain package for resource number 0x7f050000
08-01 22:55:07.516: W/ResourceType(65): Resources don't contain package for resource number 0x7f060000
08-01 22:55:07.667: W/ResourceType(65): Resources don't contain package for resource number 0x7f060001
08-01 22:55:08.236: D/AndroidRuntime(210): --- registering native functions ---
08-01 22:55:10.246: I/MediaProvider(179): Upgrading media database from version 0 to 78, which will destroy all old data
08-01 22:55:10.656: D/dalvikvm(219): DexOpt: load 677ms, verify 1526ms, opt 36ms
08-01 22:55:10.746: D/installd(31): DexInv: --- END '/system/app/Mms.apk' (success) ---
08-01 22:55:10.757: I/ActivityManager(65): Starting activity: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.xlnc.webapp/.WirelessDropActivity }
08-01 22:55:10.827: D/AndroidRuntime(210): Shutting down VM
08-01 22:55:10.827: D/dalvikvm(210): DestroyJavaVM waiting for non-daemon threads to exit
08-01 22:55:10.836: D/dalvikvm(210): DestroyJavaVM shutting VM down
08-01 22:55:10.836: D/dalvikvm(210): HeapWorker thread shutting down
08-01 22:55:10.836: D/dalvikvm(210): HeapWorker thread has shut down
08-01 22:55:10.836: D/jdwp(210): JDWP shutting down net...
08-01 22:55:10.836: I/jdwp(210): adbd disconnected
08-01 22:55:10.836: D/dalvikvm(210): VM cleaning up
08-01 22:55:10.916: E/AndroidRuntime(210): ERROR: thread attach failed
08-01 22:55:10.927: D/dalvikvm(210): LinearAlloc 0x0 used 637292 of 5242880 (12%)
08-01 22:55:11.076: I/ActivityManager(65): Start proc com.xlnc.webapp for activity com.xlnc.webapp/.WirelessDropActivity: pid=227 uid=10024 gids={3003}
08-01 22:55:11.746: D/(212): unable to unlink '/data/data/com.android.mms/shared_prefs/com.android.mms_preferences.xml.bak': No such file or directory (errno=2)
08-01 22:55:11.746: I/dalvikvm(165): Debugger has detached; object registry had 1 entries
08-01 22:55:11.756: D/(212): unable to unlink '/data/data/com.android.mms/shared_prefs/_has_set_default_values.xml.bak': No such file or directory (errno=2)
08-01 22:55:11.926: I/ARMAssembler(65): generated scanline__00000177:03515104_00000001_00000000 [ 73 ipp] (95 ins) at [0x3e1138:0x3e12b4] in 1170007 ns
08-01 22:55:12.026: I/ARMAssembler(65): generated scanline__00000077:03545404_00000004_00000000 [ 47 ipp] (67 ins) at [0x44e5b8:0x44e6c4] in 585431 ns
08-01 22:55:12.486: D/ddm-heap(212): Got feature list request
08-01 22:55:12.597: D/ddm-heap(227): Got feature list request
08-01 22:55:12.666: D/ddm-heap(165): Got feature list request
08-01 22:55:13.176: D/ddm-heap(179): Got feature list request
08-01 22:55:13.227: I/ActivityManager(65): Displayed activity com.xlnc.webapp/.WirelessDropActivity: 2203 ms (total 2203 ms)
08-01 22:55:13.346: I/ARMAssembler(65): generated scanline__00000077:03545404_00000A04_00000000 [ 29 ipp] (51 ins) at [0x437570:0x43763c] in 411860 ns
08-01 22:55:13.776: D/(165): unable to unlink '/data/data/com.android.alarmclock/shared_prefs/AlarmClock.xml.bak': No such file or directory (errno=2)
08-01 22:55:13.808: W/BackupManagerService(65): dataChanged but no participant pkg='com.android.providers.settings' uid=10017
08-01 22:55:13.877: W/BackupManagerService(65): dataChanged but no participant pkg='com.android.providers.settings' uid=10017
08-01 22:55:13.916: I/ActivityManager(65): Start proc com.android.email for broadcast com.android.email/com.android.exchange.BootReceiver: pid=240 uid=10023 gids={3003, 1015}
08-01 22:55:14.126: D/ddm-heap(240): Got feature list request
08-01 22:55:14.176: D/dalvikvm(29): GC freed 276 objects / 10576 bytes in 266ms
08-01 22:55:14.309: D/installd(31): DexInv: --- BEGIN '/system/app/Email.apk' ---
08-01 22:55:14.346: D/dalvikvm(29): GC freed 45 objects / 2000 bytes in 164ms
08-01 22:55:14.487: D/dalvikvm(29): GC freed 2 objects / 48 bytes in 139ms
08-01 22:55:17.596: D/dalvikvm(246): DexOpt: load 283ms, verify 2203ms, opt 85ms
08-01 22:55:17.665: D/installd(31): DexInv: --- END '/system/app/Email.apk' (success) ---
08-01 22:55:17.806: I/ActivityThread(240): Publishing provider com.android.email.provider: com.android.email.provider.EmailProvider
08-01 22:55:17.866: I/ActivityThread(240): Publishing provider com.android.email.attachmentprovider: com.android.email.provider.AttachmentProvider
08-01 22:55:18.036: D/Exchange(240): BootReceiver onReceive
08-01 22:55:18.086: D/EAS SyncManager(240): !!! EAS SyncManager, onCreate
08-01 22:55:18.456: D/EAS SyncManager(240): !!! EAS SyncManager, onStartCommand
08-01 22:55:18.586: D/EAS SyncManager(240): !!! EAS SyncManager, stopping self
08-01 22:55:19.186: I/ActivityManager(65): Start proc com.svox.pico for broadcast com.svox.pico/.VoiceDataInstallerReceiver: pid=252 uid=10012 gids={}
08-01 22:55:19.386: D/ddm-heap(252): Got feature list request
08-01 22:55:19.416: D/Eas Debug(240): Logging: 
08-01 22:55:19.456: D/installd(31): DexInv: --- BEGIN '/system/app/PicoTts.apk' ---
08-01 22:55:19.736: D/dalvikvm(258): DexOpt: load 40ms, verify 22ms, opt 1ms
08-01 22:55:19.736: D/installd(31): DexInv: --- END '/system/app/PicoTts.apk' (success) ---
08-01 22:55:19.821: D/EAS SyncManager(240): !!! EAS SyncManager, onDestroy
08-01 22:55:19.947: D/MediaScanner(179): opendir /system/media/ failed, errno: 2
08-01 22:55:19.966: D/MediaScanner(179):  prescan time: 12539ms
08-01 22:55:19.980: D/MediaScanner(179):     scan time: 48ms
08-01 22:55:19.980: D/MediaScanner(179): postscan time: 1ms
08-01 22:55:19.980: D/MediaScanner(179):    total time: 12588ms
08-01 22:55:20.124: D/MediaScannerService(179): done scanning volume internal
08-01 22:55:23.136: I/Notification(227): show Notification Entered
08-01 22:55:23.546: I/HTTPSERVICE(227): Creating and starting httpService
08-01 22:55:28.896: W/ResourceType(65): Resources don't contain package for resource number 0x7f0700e5
08-01 22:55:28.896: W/ResourceType(65): Resources don't contain package for resource number 0x7f020031
08-01 22:55:28.896: W/ResourceType(65): Resources don't contain package for resource number 0x7f020030
08-01 22:55:28.896: W/ResourceType(65): Resources don't contain package for resource number 0x7f050000
08-01 22:55:28.987: W/ResourceType(65): Resources don't contain package for resource number 0x7f060000
08-01 22:55:28.987: W/ResourceType(65): Resources don't contain package for resource number 0x7f060001
08-01 22:55:59.739: W/WindowManager(65): Key dispatching timed out sending to Service Started
08-01 22:55:59.739: W/WindowManager(65): Dispatch state: null
08-01 22:55:59.746: W/WindowManager(65): Current state:  {{null to Window{44e51758 Service Started paused=false} @ 1343861759751 lw=Window{44e51758 Service Started paused=false} lb=android.os.BinderProxy@44e515e0 fin=false gfw=true ed=true tts=0 wf=false fp=false mcf=Window{44e51758 Service Started paused=false}}}
08-01 22:55:59.816: I/ActivityManager(65): ANR in process: com.xlnc.webapp (last in com.xlnc.webapp)
08-01 22:55:59.816: I/ActivityManager(65): Annotation: keyDispatchingTimedOut
08-01 22:55:59.816: I/ActivityManager(65): CPU usage:
08-01 22:55:59.816: I/ActivityManager(65): Load: 1.45 / 0.77 / 0.29
08-01 22:55:59.816: I/ActivityManager(65): CPU usage from 30971ms to 54ms ago:
08-01 22:55:59.816: I/ActivityManager(65):   system_server: 4% = 2% user + 1% kernel / faults: 24 minor
08-01 22:55:59.816: I/ActivityManager(65):   com.svox.pico: 1% = 0% user + 0% kernel / faults: 2607 minor
08-01 22:55:59.816: I/ActivityManager(65):   d.process.acore: 0% = 0% user + 0% kernel / faults: 3 minor
08-01 22:55:59.816: I/ActivityManager(65):   m.android.phone: 0% = 0% user + 0% kernel / faults: 1 minor
08-01 22:55:59.816: I/ActivityManager(65):   qemud: 0% = 0% user + 0% kernel
08-01 22:55:59.816: I/ActivityManager(65):   adbd: 0% = 0% user + 0% kernel
08-01 22:55:59.816: I/ActivityManager(65):   com.xlnc.webapp: 0% = 0% user + 0% kernel
08-01 22:55:59.816: I/ActivityManager(65):   pdflush: 0% = 0% user + 0% kernel
08-01 22:55:59.816: I/ActivityManager(65):   logcat: 0% = 0% user + 0% kernel
08-01 22:55:59.816: I/ActivityManager(65): TOTAL: 5% = 3% user + 1% kernel
08-01 22:55:59.816: I/Process(65): Sending signal. PID: 227 SIG: 3
08-01 22:55:59.816: I/dalvikvm(227): threadid=7: reacting to signal 3
08-01 22:55:59.836: I/dalvikvm(227): Wrote stack trace to '/data/anr/traces.txt'
08-01 22:56:00.069: I/Process(65): Sending signal. PID: 65 SIG: 3
08-01 22:56:00.069: I/dalvikvm(65): threadid=7: reacting to signal 3
08-01 22:56:00.146: I/dalvikvm(65): Wrote stack trace to '/data/anr/traces.txt'
08-01 22:56:00.413: I/Process(65): Sending signal. PID: 252 SIG: 3
08-01 22:56:00.413: I/dalvikvm(252): threadid=7: reacting to signal 3
08-01 22:56:00.436: I/dalvikvm(252): Wrote stack trace to '/data/anr/traces.txt'
08-01 22:56:00.655: I/Process(65): Sending signal. PID: 240 SIG: 3
08-01 22:56:00.655: I/dalvikvm(240): threadid=7: reacting to signal 3
08-01 22:56:00.676: I/dalvikvm(240): Wrote stack trace to '/data/anr/traces.txt'
08-01 22:56:00.886: I/Process(65): Sending signal. PID: 165 SIG: 3
08-01 22:56:00.886: I/dalvikvm(165): threadid=7: reacting to signal 3
08-01 22:56:00.906: I/dalvikvm(165): Wrote stack trace to '/data/anr/traces.txt'
08-01 22:56:01.142: I/Process(65): Sending signal. PID: 212 SIG: 3
08-01 22:56:01.142: I/dalvikvm(212): threadid=7: reacting to signal 3
08-01 22:56:01.256: I/dalvikvm(212): Wrote stack trace to '/data/anr/traces.txt'
08-01 22:56:01.397: I/Process(65): Sending signal. PID: 179 SIG: 3
08-01 22:56:01.397: I/dalvikvm(179): threadid=7: reacting to signal 3
08-01 22:56:01.418: I/dalvikvm(179): Wrote stack trace to '/data/anr/traces.txt'
08-01 22:56:01.630: I/Process(65): Sending signal. PID: 118 SIG: 3
08-01 22:56:01.630: I/dalvikvm(118): threadid=7: reacting to signal 3
08-01 22:56:01.716: I/dalvikvm(118): Wrote stack trace to '/data/anr/traces.txt'
08-01 22:56:01.859: I/Process(65): Sending signal. PID: 143 SIG: 3
08-01 22:56:01.859: I/dalvikvm(143): threadid=7: reacting to signal 3
08-01 22:56:01.877: I/dalvikvm(143): Wrote stack trace to '/data/anr/traces.txt'
08-01 22:56:02.135: I/Process(65): Sending signal. PID: 116 SIG: 3
08-01 22:56:02.135: I/dalvikvm(116): threadid=7: reacting to signal 3
08-01 22:56:02.176: I/dalvikvm(116): Wrote stack trace to '/data/anr/traces.txt'
08-01 22:56:02.406: W/WindowManager(65): No window to dispatch pointer action 1
08-01 22:56:02.476: W/WindowManager(65): No window to dispatch pointer action 1
08-01 22:56:02.646: I/ARMAssembler(65): generated scanline__00000077:03515104_00000000_00000000 [ 33 ipp] (47 ins) at [0x480dd8:0x480e94] in 473574 ns
08-01 22:56:02.769: I/ARMAssembler(65): generated scanline__00000177:03515104_00001001_00000000 [ 91 ipp] (114 ins) at [0x480e98:0x481060] in 786862 ns
08-01 22:56:05.066: I/ActivityManager(65): Killing process com.xlnc.webapp (pid=227) at user's request
08-01 22:56:05.086: I/Process(65): Sending signal. PID: 227 SIG: 9
08-01 22:56:05.226: I/ActivityManager(65): Process com.xlnc.webapp (pid 227) has died.
08-01 22:56:05.226: W/ActivityManager(65): Scheduling restart of crashed service com.xlnc.webapp/.WebServerService in 83846ms
08-01 22:56:05.236: I/WindowManager(65): WIN DEATH: Window{44e72108 com.xlnc.webapp/com.xlnc.webapp.WirelessDropActivity paused=false}
08-01 22:56:05.236: I/WindowManager(65): WIN DEATH: Window{44e51758 Service Started paused=false}
08-01 22:56:05.346: E/gralloc(65): [unregister] handle 0x4811e8 still locked (state=40000001)
08-01 22:56:05.367: I/UsageStats(65): Unexpected resume of com.android.launcher while already resumed in com.xlnc.webapp
08-01 22:56:05.637: W/InputManagerService(65): Got RemoteException sending setActive(false) notification to pid 227 uid 10024
08-01 22:56:05.676: E/ActivityThread(65): Failed to find provider info for android.server.checkin
08-01 22:56:05.687: W/Checkin(65): Can't log event SYSTEM_SERVICE_LOOPING: java.lang.IllegalArgumentException: Unknown URL content://android.server.checkin/events

Upvotes: 3

Views: 6915

Answers (1)

Oliver
Oliver

Reputation: 1279

The onCreate() in the Service is called from the GUI thread. You are trying to run the whole web server in the GUI thread: you not return but end up "forever" in WebServer.runServer(). For any "long" running task, you need to put this into a new, non-GUI thread, to NOT block the GUI thread.

The Thread class even gives you functions to cancel the thread, which throws an easy catchable InteruptedException for selects() and other things waiting. There is no need of some potentially dangerous STATIC "running" flag. Please always try to work around any kind of static data.

Upvotes: 4

Related Questions