Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TIMOB-9831 Include the presence/absence of running Services when determi... #2658

Merged
merged 1 commit into from
Jul 30, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.lang.ref.WeakReference;
import java.util.concurrent.CountDownLatch;

import org.appcelerator.kroll.common.TiConfig;
import org.appcelerator.kroll.common.TiMessenger;
import org.appcelerator.kroll.util.KrollAssetHelper;

Expand Down Expand Up @@ -43,6 +44,7 @@ public abstract class KrollRuntime implements Handler.Callback

private static KrollRuntime instance;
private static int activityRefCount = 0;
private static int serviceRefCount = 0;

private WeakReference<KrollApplication> krollApplication;
private KrollRuntimeThread thread;
Expand Down Expand Up @@ -178,6 +180,10 @@ protected void doInit()
public void dispose()
{

if (TiConfig.LOGD) {
Log.d(TAG, "Disposing runtime.");
}

// Set state to released when since we have not fully disposed of it yet
synchronized (runtimeState) {
runtimeState = State.RELEASED;
Expand Down Expand Up @@ -303,36 +309,42 @@ private static void waitForInit()
}
}

// The runtime instance keeps an internal reference count of all Titanium activities
// that have been opened by the TiApplication. When the ref count drops to 0,
// (i.e. all activities have been destroyed), we dispose of all runtime data.
public static void incrementActivityRefCount()
private static void syncInit()
{
activityRefCount++;
if (activityRefCount == 1 && instance != null) {
waitForInit();
waitForInit();

// When the process is re-entered, it is either in the RELEASED or DISPOSED state. If it is in the RELEASED
// state, that means we have not disposed of the runtime from the previous launch. In that case, we set the
// state to RELAUNCHED. If we are in the DISPOSED state, we need to re-initialize the runtime here.
synchronized (runtimeState) {
if (runtimeState == State.DISPOSED) {
instance.initLatch = new CountDownLatch(1);
instance.handler.sendEmptyMessage(MSG_INIT);
// When the process is re-entered, it is either in the RELEASED or DISPOSED state. If it is in the RELEASED
// state, that means we have not disposed of the runtime from the previous launch. In that case, we set the
// state to RELAUNCHED. If we are in the DISPOSED state, we need to re-initialize the runtime here.
synchronized (runtimeState) {
if (runtimeState == State.DISPOSED) {
instance.initLatch = new CountDownLatch(1);
instance.handler.sendEmptyMessage(MSG_INIT);

} else if (runtimeState == State.RELEASED) {
runtimeState = State.RELAUNCHED;
}
} else if (runtimeState == State.RELEASED) {
runtimeState = State.RELAUNCHED;
}
}

waitForInit();
}

waitForInit();
// The runtime instance keeps an internal reference count of all Titanium activities
// and all Titanium services that have been opened/started by the application.
// When the ref counts for both of them drop to 0, then we know there is nothing left
// to execute on the runtime, and we can therefore dispose of it.
public static void incrementActivityRefCount()
{
activityRefCount++;
if ((activityRefCount + serviceRefCount) == 1 && instance != null) {
syncInit();
}
}

public static void decrementActivityRefCount()
{
activityRefCount--;
if (activityRefCount > 0 || instance == null) {
if ((activityRefCount + serviceRefCount) > 0 || instance == null) {
return;
}

Expand All @@ -344,6 +356,30 @@ public static int getActivityRefCount()
return activityRefCount;
}

// Similar to {@link #incrementActivityRefCount} but for a Titanium Service.
public static void incrementServiceRefCount()
{
serviceRefCount++;
if ((activityRefCount + serviceRefCount) == 1 && instance != null) {
syncInit();
}
}

public static void decrementServiceRefCount()
{
serviceRefCount--;
if ((activityRefCount + serviceRefCount) > 0 || instance == null) {
return;
}

instance.dispose();
}

public static int getServiceRefCount()
{
return serviceRefCount;
}

private void internalDispose()
{
synchronized (runtimeState) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
/**
* Appcelerator Titanium Mobile
* Copyright (c) 2009-2010 by Appcelerator, Inc. All Rights Reserved.
* Copyright (c) 2009-2012 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the Apache Public License
* Please see the LICENSE included with this distribution for details.
*/
package org.appcelerator.titanium;

import java.util.concurrent.atomic.AtomicInteger;

import org.appcelerator.kroll.KrollRuntime;
import org.appcelerator.titanium.proxy.ServiceProxy;

import android.app.Service;
Expand Down Expand Up @@ -74,4 +75,18 @@ public int nextServiceInstanceId()
{
return proxyCounter.incrementAndGet();
}

@Override
public void onCreate()
{
super.onCreate();
KrollRuntime.incrementServiceRefCount();
}

@Override
public void onDestroy()
{
super.onDestroy();
KrollRuntime.decrementServiceRefCount();
}
}