Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
R
react-native-threads
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Jira
Jira
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
冷佳娟
react-native-threads
Commits
ecb4030d
Commit
ecb4030d
authored
Sep 16, 2017
by
Travis Nuttall
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
get android working
parent
30000648
Changes
17
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
835 additions
and
39 deletions
+835
-39
android/build.gradle
android/build.gradle
+5
-0
android/gradle/wrapper/gradle-wrapper.jar
android/gradle/wrapper/gradle-wrapper.jar
+0
-0
android/gradle/wrapper/gradle-wrapper.properties
android/gradle/wrapper/gradle-wrapper.properties
+6
-0
android/gradlew
android/gradlew
+160
-0
android/gradlew.bat
android/gradlew.bat
+90
-0
android/src/main/java/com/reactlibrary/BaseReactPackage.java
android/src/main/java/com/reactlibrary/BaseReactPackage.java
+62
-0
android/src/main/java/com/reactlibrary/JSThread.java
android/src/main/java/com/reactlibrary/JSThread.java
+72
-0
android/src/main/java/com/reactlibrary/RNThreadModule.java
android/src/main/java/com/reactlibrary/RNThreadModule.java
+201
-7
android/src/main/java/com/reactlibrary/RNThreadPackage.java
android/src/main/java/com/reactlibrary/RNThreadPackage.java
+22
-11
android/src/main/java/com/reactlibrary/ReactContextBuilder.java
...d/src/main/java/com/reactlibrary/ReactContextBuilder.java
+136
-0
android/src/main/java/com/reactlibrary/ThreadSelfModule.java
android/src/main/java/com/reactlibrary/ThreadSelfModule.java
+34
-0
android/src/main/java/com/reactlibrary/UIManagerStubModule.java
...d/src/main/java/com/reactlibrary/UIManagerStubModule.java
+16
-0
example/ThreadExample/android/app/build.gradle
example/ThreadExample/android/app/build.gradle
+1
-0
example/ThreadExample/android/app/src/main/java/com/threadexample/MainApplication.java
.../app/src/main/java/com/threadexample/MainApplication.java
+3
-1
example/ThreadExample/android/settings.gradle
example/ThreadExample/android/settings.gradle
+2
-0
example/ThreadExample/index.android.js
example/ThreadExample/index.android.js
+23
-18
package.json
package.json
+2
-2
No files found.
android/build.gradle
View file @
ecb4030d
...
...
@@ -28,6 +28,11 @@ android {
repositories
{
mavenCentral
()
jcenter
()
maven
{
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
url
"$rootDir/../node_modules/react-native/android"
}
}
dependencies
{
...
...
android/gradle/wrapper/gradle-wrapper.jar
0 → 100644
View file @
ecb4030d
File added
android/gradle/wrapper/gradle-wrapper.properties
0 → 100644
View file @
ecb4030d
#Sat Sep 16 10:14:34 MDT 2017
distributionBase
=
GRADLE_USER_HOME
distributionPath
=
wrapper/dists
zipStoreBase
=
GRADLE_USER_HOME
zipStorePath
=
wrapper/dists
distributionUrl
=
https
\:
//services.gradle.org/distributions/gradle-3.3-all.zip
android/gradlew
0 → 100644
View file @
ecb4030d
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS
=
""
APP_NAME
=
"Gradle"
APP_BASE_NAME
=
`
basename
"
$0
"
`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD
=
"maximum"
warn
(
)
{
echo
"
$*
"
}
die
(
)
{
echo
echo
"
$*
"
echo
exit
1
}
# OS specific support (must be 'true' or 'false').
cygwin
=
false
msys
=
false
darwin
=
false
case
"
`
uname
`
"
in
CYGWIN
*
)
cygwin
=
true
;;
Darwin
*
)
darwin
=
true
;;
MINGW
*
)
msys
=
true
;;
esac
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG
=
"
$0
"
# Need this for relative symlinks.
while
[
-h
"
$PRG
"
]
;
do
ls
=
`
ls
-ld
"
$PRG
"
`
link
=
`
expr
"
$ls
"
:
'.*-> \(.*\)$'
`
if
expr
"
$link
"
:
'/.*'
>
/dev/null
;
then
PRG
=
"
$link
"
else
PRG
=
`
dirname
"
$PRG
"
`
"/
$link
"
fi
done
SAVED
=
"
`
pwd
`
"
cd
"
`
dirname
\"
$PRG
\"
`
/"
>
/dev/null
APP_HOME
=
"
`
pwd
-P
`
"
cd
"
$SAVED
"
>
/dev/null
CLASSPATH
=
$APP_HOME
/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if
[
-n
"
$JAVA_HOME
"
]
;
then
if
[
-x
"
$JAVA_HOME
/jre/sh/java"
]
;
then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD
=
"
$JAVA_HOME
/jre/sh/java"
else
JAVACMD
=
"
$JAVA_HOME
/bin/java"
fi
if
[
!
-x
"
$JAVACMD
"
]
;
then
die
"ERROR: JAVA_HOME is set to an invalid directory:
$JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD
=
"java"
which java
>
/dev/null 2>&1
||
die
"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if
[
"
$cygwin
"
=
"false"
-a
"
$darwin
"
=
"false"
]
;
then
MAX_FD_LIMIT
=
`
ulimit
-H
-n
`
if
[
$?
-eq
0
]
;
then
if
[
"
$MAX_FD
"
=
"maximum"
-o
"
$MAX_FD
"
=
"max"
]
;
then
MAX_FD
=
"
$MAX_FD_LIMIT
"
fi
ulimit
-n
$MAX_FD
if
[
$?
-ne
0
]
;
then
warn
"Could not set maximum file descriptor limit:
$MAX_FD
"
fi
else
warn
"Could not query maximum file descriptor limit:
$MAX_FD_LIMIT
"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if
$darwin
;
then
GRADLE_OPTS
=
"
$GRADLE_OPTS
\"
-Xdock:name=
$APP_NAME
\"
\"
-Xdock:icon=
$APP_HOME
/media/gradle.icns
\"
"
fi
# For Cygwin, switch paths to Windows format before running java
if
$cygwin
;
then
APP_HOME
=
`
cygpath
--path
--mixed
"
$APP_HOME
"
`
CLASSPATH
=
`
cygpath
--path
--mixed
"
$CLASSPATH
"
`
JAVACMD
=
`
cygpath
--unix
"
$JAVACMD
"
`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW
=
`
find
-L
/
-maxdepth
1
-mindepth
1
-type
d 2>/dev/null
`
SEP
=
""
for
dir
in
$ROOTDIRSRAW
;
do
ROOTDIRS
=
"
$ROOTDIRS$SEP$dir
"
SEP
=
"|"
done
OURCYGPATTERN
=
"(^(
$ROOTDIRS
))"
# Add a user-defined pattern to the cygpath arguments
if
[
"
$GRADLE_CYGPATTERN
"
!=
""
]
;
then
OURCYGPATTERN
=
"
$OURCYGPATTERN
|(
$GRADLE_CYGPATTERN
)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i
=
0
for
arg
in
"
$@
"
;
do
CHECK
=
`
echo
"
$arg
"
|egrep
-c
"
$OURCYGPATTERN
"
-
`
CHECK2
=
`
echo
"
$arg
"
|egrep
-c
"^-"
`
### Determine if an option
if
[
$CHECK
-ne
0
]
&&
[
$CHECK2
-eq
0
]
;
then
### Added a condition
eval
`
echo
args
$i
`
=
`
cygpath
--path
--ignore
--mixed
"
$arg
"
`
else
eval
`
echo
args
$i
`
=
"
\"
$arg
\"
"
fi
i
=
$((
i+1
))
done
case
$i
in
(
0
)
set
--
;;
(
1
)
set
--
"
$args0
"
;;
(
2
)
set
--
"
$args0
"
"
$args1
"
;;
(
3
)
set
--
"
$args0
"
"
$args1
"
"
$args2
"
;;
(
4
)
set
--
"
$args0
"
"
$args1
"
"
$args2
"
"
$args3
"
;;
(
5
)
set
--
"
$args0
"
"
$args1
"
"
$args2
"
"
$args3
"
"
$args4
"
;;
(
6
)
set
--
"
$args0
"
"
$args1
"
"
$args2
"
"
$args3
"
"
$args4
"
"
$args5
"
;;
(
7
)
set
--
"
$args0
"
"
$args1
"
"
$args2
"
"
$args3
"
"
$args4
"
"
$args5
"
"
$args6
"
;;
(
8
)
set
--
"
$args0
"
"
$args1
"
"
$args2
"
"
$args3
"
"
$args4
"
"
$args5
"
"
$args6
"
"
$args7
"
;;
(
9
)
set
--
"
$args0
"
"
$args1
"
"
$args2
"
"
$args3
"
"
$args4
"
"
$args5
"
"
$args6
"
"
$args7
"
"
$args8
"
;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function
splitJvmOpts
()
{
JVM_OPTS
=(
"
$@
"
)
}
eval
splitJvmOpts
$DEFAULT_JVM_OPTS
$JAVA_OPTS
$GRADLE_OPTS
JVM_OPTS[
${#
JVM_OPTS
[*]
}
]=
"-Dorg.gradle.appname=
$APP_BASE_NAME
"
exec
"
$JAVACMD
"
"
${
JVM_OPTS
[@]
}
"
-classpath
"
$CLASSPATH
"
org.gradle.wrapper.GradleWrapperMain
"
$@
"
android/gradlew.bat
0 → 100644
View file @
ecb4030d
@if
"
%DEBUG%
"
==
""
@echo
off
@rem ##########################################################################
@rem
@rem
Gradle
startup
script
for
Windows
@rem
@rem ##########################################################################
@rem
Set
local
scope
for
the
variables
with
windows
NT
shell
if
"
%OS%
"
==
"Windows_NT"
setlocal
@rem
Add
default
JVM
options
here
.
You
can
also
use
JAVA_OPTS
and
GRADLE_OPTS
to
pass
JVM
options
to
this
script
.
set
DEFAULT_JVM_OPTS
=
set
DIRNAME
=
%~dp0
if
"
%DIRNAME%
"
==
""
set
DIRNAME
=
.
set
APP_BASE_NAME
=
%~n0
set
APP_HOME
=
%DIRNAME%
@rem
Find
java
.exe
if
defined
JAVA_HOME
goto
findJavaFromJavaHome
set
JAVA_EXE
=
java
.exe
%JAVA_EXE%
-version
>
NUL
2
>&
1
if
"
%ERRORLEVEL%
"
==
"0"
goto
init
echo
.
echo
ERROR
:
JAVA_HOME
is
not
set
and
no
'java'
command
could
be
found
in
your
PATH
.
echo
.
echo
Please
set
the
JAVA_HOME
variable
in
your
environment
to
match
the
echo
location
of
your
Java
installation
.
goto
fail
:findJavaFromJavaHome
set
JAVA_HOME
=
%JAVA
_HOME:
"=
%
set JAVA_EXE=
%JAVA_HOME%
/bin/java.exe
if exist "
%JAVA_EXE%
" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory:
%JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "
%OS%
" == "
Windows_NT
" goto win9xME_args
if "
%
@eval
[
2
+
2
]
" == "
4
" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "
x
%
~
1
" == "
x
" goto execute
set CMD_LINE_ARGS=
%
*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=
%
$
:execute
@rem Setup the command line
set CLASSPATH=
%APP_HOME%
\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"
%JAVA_EXE%
"
%DEFAULT_JVM_OPTS%
%JAVA_OPTS%
%GRADLE_OPTS%
"
-Dorg
.gradle.appname
=
%APP_BASE_NAME%
" -classpath "
%CLASSPATH%
" org.gradle.wrapper.GradleWrapperMain
%CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "
%ERRORLEVEL%
"=="
0
" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code
!
if not "" == "
%GRADLE_EXIT_CONSOLE%
" exit 1
exit /b 1
:mainEnd
if "
%OS%
"=="
Windows_NT
" endlocal
:omega
android/src/main/java/com/reactlibrary/BaseReactPackage.java
0 → 100644
View file @
ecb4030d
package
com.reactlibrary
;
import
com.facebook.react.ReactInstanceManager
;
import
com.facebook.react.ReactPackage
;
import
com.facebook.react.bridge.NativeModule
;
import
com.facebook.react.bridge.ReactApplicationContext
;
import
com.facebook.react.devsupport.JSCHeapCapture
;
import
com.facebook.react.modules.appstate.AppStateModule
;
import
com.facebook.react.modules.core.ExceptionsManagerModule
;
import
com.facebook.react.modules.core.Timing
;
import
com.facebook.react.modules.debug.SourceCodeModule
;
import
com.facebook.react.modules.intent.IntentModule
;
import
com.facebook.react.modules.location.LocationModule
;
import
com.facebook.react.modules.netinfo.NetInfoModule
;
import
com.facebook.react.modules.network.NetworkingModule
;
import
com.facebook.react.modules.storage.AsyncStorageModule
;
import
com.facebook.react.modules.systeminfo.AndroidInfoModule
;
import
com.facebook.react.modules.vibration.VibrationModule
;
import
com.facebook.react.modules.websocket.WebSocketModule
;
import
com.facebook.react.uimanager.ViewManager
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.List
;
public
class
BaseReactPackage
implements
ReactPackage
{
private
final
ReactInstanceManager
reactInstanceManager
;
public
BaseReactPackage
(
ReactInstanceManager
reactInstanceManager
)
{
this
.
reactInstanceManager
=
reactInstanceManager
;
}
@Override
public
List
<
NativeModule
>
createNativeModules
(
ReactApplicationContext
catalystApplicationContext
)
{
return
Arrays
.<
NativeModule
>
asList
(
// Core list
new
AndroidInfoModule
(),
new
ExceptionsManagerModule
(
reactInstanceManager
.
getDevSupportManager
()),
new
AppStateModule
(
catalystApplicationContext
),
new
Timing
(
catalystApplicationContext
,
reactInstanceManager
.
getDevSupportManager
()),
new
UIManagerStubModule
(
catalystApplicationContext
),
new
SourceCodeModule
(
catalystApplicationContext
),
new
JSCHeapCapture
(
catalystApplicationContext
),
// Main list
new
AsyncStorageModule
(
catalystApplicationContext
),
new
IntentModule
(
catalystApplicationContext
),
new
LocationModule
(
catalystApplicationContext
),
new
NetworkingModule
(
catalystApplicationContext
),
new
NetInfoModule
(
catalystApplicationContext
),
new
VibrationModule
(
catalystApplicationContext
),
new
WebSocketModule
(
catalystApplicationContext
),
new
ThreadSelfModule
(
catalystApplicationContext
)
);
}
@Override
public
List
<
ViewManager
>
createViewManagers
(
ReactApplicationContext
reactContext
)
{
return
new
ArrayList
<>(
0
);
}
}
\ No newline at end of file
android/src/main/java/com/reactlibrary/JSThread.java
0 → 100644
View file @
ecb4030d
package
com.reactlibrary
;
import
com.facebook.react.bridge.ReactApplicationContext
;
import
com.facebook.react.modules.core.DeviceEventManagerModule
;
import
java.util.Random
;
public
class
JSThread
{
private
int
id
;
private
String
jsSlugname
;
private
ReactApplicationContext
reactContext
;
public
JSThread
(
String
jsSlugname
)
{
this
.
id
=
Math
.
abs
(
new
Random
().
nextInt
());
this
.
jsSlugname
=
jsSlugname
;
}
public
int
getThreadId
()
{
return
this
.
id
;
}
public
String
getName
()
{
return
jsSlugname
;
}
public
void
runFromContext
(
ReactApplicationContext
context
,
ReactContextBuilder
reactContextBuilder
)
throws
Exception
{
if
(
reactContext
!=
null
)
{
return
;
}
reactContext
=
reactContextBuilder
.
build
();
ThreadSelfModule
threadSelfModule
=
reactContext
.
getNativeModule
(
ThreadSelfModule
.
class
);
threadSelfModule
.
initialize
(
id
,
context
);
}
public
void
postMessage
(
String
message
)
{
if
(
reactContext
==
null
)
{
return
;
}
reactContext
.
getJSModule
(
DeviceEventManagerModule
.
RCTDeviceEventEmitter
.
class
)
.
emit
(
"ThreadMessage"
,
message
);
}
public
void
onHostResume
()
{
if
(
reactContext
==
null
)
{
return
;
}
reactContext
.
onHostResume
(
null
);
}
public
void
onHostPause
()
{
if
(
reactContext
==
null
)
{
return
;
}
reactContext
.
onHostPause
();
}
public
void
terminate
()
{
if
(
reactContext
==
null
)
{
return
;
}
reactContext
.
onHostPause
();
reactContext
.
destroy
();
reactContext
=
null
;
}
}
\ No newline at end of file
android/src/main/java/com/reactlibrary/RNThreadModule.java
View file @
ecb4030d
package
com.reactlibrary
;
import
android.os.Handler
;
import
android.os.Looper
;
import
android.util.Log
;
import
com.facebook.react.ReactNativeHost
;
import
com.facebook.react.ReactInstanceManager
;
import
com.facebook.react.ReactPackage
;
import
com.facebook.react.bridge.JSBundleLoader
;
import
com.facebook.react.bridge.LifecycleEventListener
;
import
com.facebook.react.bridge.Promise
;
import
com.facebook.react.bridge.ReactApplicationContext
;
import
com.facebook.react.bridge.ReactContextBaseJavaModule
;
import
com.facebook.react.bridge.ReactMethod
;
import
com.facebook.react.bridge.Callback
;
import
com.facebook.react.devsupport.interfaces.DevSupportManager
;
import
java.io.File
;
import
java.io.IOException
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.HashMap
;
import
okhttp3.OkHttpClient
;
import
okhttp3.Request
;
import
okhttp3.Response
;
import
okio.Okio
;
import
okio.Sink
;
public
class
RNThreadModule
extends
ReactContextBaseJavaModule
implements
LifecycleEventListener
{
public
class
RNThreadModule
extends
ReactContextBaseJavaModule
{
private
String
TAG
=
"ThreadManager"
;
private
HashMap
<
Integer
,
JSThread
>
threads
;
private
final
ReactApplicationContext
reactContex
t
;
private
ReactNativeHost
reactNativeHos
t
;
public
RNThreadModule
(
ReactApplicationContext
reactContext
)
{
private
ReactPackage
additionalThreadPackages
[];
public
RNThreadModule
(
final
ReactApplicationContext
reactContext
,
ReactNativeHost
reactNativehost
,
ReactPackage
additionalThreadPackages
[])
{
super
(
reactContext
);
this
.
reactContext
=
reactContext
;
threads
=
new
HashMap
<>();
this
.
reactNativeHost
=
reactNativehost
;
this
.
additionalThreadPackages
=
additionalThreadPackages
;
reactContext
.
addLifecycleEventListener
(
this
);
}
@Override
public
String
getName
()
{
return
"RNThread"
;
return
"ThreadManager"
;
}
@ReactMethod
public
void
startThread
(
final
String
jsFileName
,
final
Promise
promise
)
{
Log
.
d
(
TAG
,
"Starting web thread - "
+
jsFileName
);
String
jsFileSlug
=
jsFileName
.
contains
(
"/"
)
?
jsFileName
.
replaceAll
(
"/"
,
"_"
)
:
jsFileName
;
JSBundleLoader
bundleLoader
=
getDevSupportManager
().
getDevSupportEnabled
()
?
createDevBundleLoader
(
jsFileName
,
jsFileSlug
)
:
createReleaseBundleLoader
(
jsFileName
,
jsFileSlug
);
try
{
ArrayList
<
ReactPackage
>
threadPackages
=
new
ArrayList
<
ReactPackage
>(
Arrays
.
asList
(
additionalThreadPackages
));
threadPackages
.
add
(
0
,
new
BaseReactPackage
(
getReactInstanceManager
()));
ReactContextBuilder
threadContextBuilder
=
new
ReactContextBuilder
(
getReactApplicationContext
())
.
setJSBundleLoader
(
bundleLoader
)
.
setDevSupportManager
(
getDevSupportManager
())
.
setReactInstanceManager
(
getReactInstanceManager
())
.
setReactPackages
(
threadPackages
);
JSThread
thread
=
new
JSThread
(
jsFileSlug
);
thread
.
runFromContext
(
getReactApplicationContext
(),
threadContextBuilder
);
threads
.
put
(
thread
.
getThreadId
(),
thread
);
promise
.
resolve
(
thread
.
getThreadId
());
}
catch
(
Exception
e
)
{
promise
.
reject
(
e
);
getDevSupportManager
().
handleException
(
e
);
}
}
@ReactMethod
public
void
stopThread
(
final
int
threadId
)
{
final
JSThread
thread
=
threads
.
get
(
threadId
);
if
(
thread
==
null
)
{
Log
.
d
(
TAG
,
"Cannot stop thread - thread is null for id "
+
threadId
);
return
;
}
new
Handler
(
Looper
.
getMainLooper
()).
post
(
new
Runnable
()
{
@Override
public
void
run
()
{
thread
.
terminate
();
threads
.
remove
(
threadId
);
}
});
}
@ReactMethod
public
void
postThreadMessage
(
int
threadId
,
String
message
)
{
JSThread
thread
=
threads
.
get
(
threadId
);
if
(
thread
==
null
)
{
Log
.
d
(
TAG
,
"Cannot post message to thread - thread is null for id "
+
threadId
);
return
;
}
thread
.
postMessage
(
message
);
}
@Override
public
void
onHostResume
()
{
new
Handler
(
Looper
.
getMainLooper
()).
post
(
new
Runnable
()
{
@Override
public
void
run
()
{
for
(
int
threadId
:
threads
.
keySet
())
{
threads
.
get
(
threadId
).
onHostResume
();
}
}
});
}
@Override
public
void
onHostPause
()
{
new
Handler
(
Looper
.
getMainLooper
()).
post
(
new
Runnable
()
{
@Override
public
void
run
()
{
for
(
int
threadId
:
threads
.
keySet
())
{
threads
.
get
(
threadId
).
onHostPause
();
}
}
});
}
@Override
public
void
onHostDestroy
()
{
Log
.
d
(
TAG
,
"onHostDestroy - Clean JS Threads"
);
new
Handler
(
Looper
.
getMainLooper
()).
post
(
new
Runnable
()
{
@Override
public
void
run
()
{
for
(
int
threadId
:
threads
.
keySet
())
{
threads
.
get
(
threadId
).
terminate
();
}
}
});
}
@Override
public
void
onCatalystInstanceDestroy
()
{
super
.
onCatalystInstanceDestroy
();
onHostDestroy
();
}
/*
* Helper methods
*/
private
JSBundleLoader
createDevBundleLoader
(
String
jsFileName
,
String
jsFileSlug
)
{
String
bundleUrl
=
bundleUrlForFile
(
jsFileName
);
String
bundleOut
=
getReactApplicationContext
().
getFilesDir
().
getAbsolutePath
()
+
"/"
+
jsFileSlug
;
Log
.
d
(
TAG
,
"createDevBundleLoader - download web thread to - "
+
bundleOut
);
downloadScriptToFileSync
(
bundleUrl
,
bundleOut
);
return
JSBundleLoader
.
createCachedBundleFromNetworkLoader
(
bundleUrl
,
bundleOut
);
}
private
JSBundleLoader
createReleaseBundleLoader
(
String
jsFileName
,
String
jsFileSlug
)
{
Log
.
d
(
TAG
,
"createReleaseBundleLoader - reading file from assets"
);
return
JSBundleLoader
.
createFileLoader
(
"assets://threads/"
+
jsFileSlug
+
".bundle"
);
}
private
ReactInstanceManager
getReactInstanceManager
()
{
return
reactNativeHost
.
getReactInstanceManager
();
}
private
DevSupportManager
getDevSupportManager
()
{
return
getReactInstanceManager
().
getDevSupportManager
();
}
private
String
bundleUrlForFile
(
final
String
fileName
)
{
// http://localhost:8081/index.android.bundle?platform=android&dev=true&hot=false&minify=false
String
sourceUrl
=
getDevSupportManager
().
getSourceUrl
().
replace
(
"http://"
,
""
);
return
"http://"
+
sourceUrl
.
split
(
"/"
)[
0
]
+
"/"
+
fileName
+
".bundle?platform=android&dev=true&hot=false&minify=false"
;
}
private
void
downloadScriptToFileSync
(
String
bundleUrl
,
String
bundleOut
)
{
OkHttpClient
client
=
new
OkHttpClient
();
final
File
out
=
new
File
(
bundleOut
);
Request
request
=
new
Request
.
Builder
()
.
url
(
bundleUrl
)
.
build
();
try
{
Response
response
=
client
.
newCall
(
request
).
execute
();
if
(!
response
.
isSuccessful
())
{
throw
new
RuntimeException
(
"Error downloading thread script - "
+
response
.
toString
());
}
Sink
output
=
Okio
.
sink
(
out
);
Okio
.
buffer
(
response
.
body
().
source
()).
readAll
(
output
);
}
catch
(
IOException
e
)
{
throw
new
RuntimeException
(
"Exception downloading thread script to file"
,
e
);
}
}
}
\ No newline at end of file
android/src/main/java/com/reactlibrary/RNThreadPackage.java
View file @
ecb4030d
package
com.reactlibrary
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.List
;
import
com.facebook.react.ReactPackage
;
import
com.facebook.react.ReactNativeHost
;
import
com.facebook.react.bridge.NativeModule
;
import
com.facebook.react.bridge.ReactApplicationContext
;
import
com.facebook.react.uimanager.ViewManager
;
import
com.facebook.react.bridge.JavaScriptModule
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.List
;
public
class
RNThreadPackage
implements
ReactPackage
{
@Override
public
List
<
NativeModule
>
createNativeModules
(
ReactApplicationContext
reactContext
)
{
return
Arrays
.<
NativeModule
>
asList
(
new
RNThreadModule
(
reactContext
));
private
ReactNativeHost
reactNativeHost
;
private
ReactPackage
additionalThreadPackages
[];
public
RNThreadPackage
(
ReactNativeHost
reactNativeHost
,
ReactPackage
...
additionalThreadPackages
)
{
this
.
reactNativeHost
=
reactNativeHost
;
this
.
additionalThreadPackages
=
additionalThreadPackages
;
}
@Override
public
List
<
ViewManager
>
createViewManagers
(
ReactApplicationContext
reactContext
)
{
return
Collections
.
emptyList
();
return
Collections
.
emptyList
();
}
@Override
public
List
<
NativeModule
>
createNativeModules
(
ReactApplicationContext
reactContext
)
{
return
Arrays
.<
NativeModule
>
asList
(
new
RNThreadModule
(
reactContext
,
reactNativeHost
,
additionalThreadPackages
)
);
}
}
}
\ No newline at end of file
android/src/main/java/com/reactlibrary/ReactContextBuilder.java
0 → 100644
View file @
ecb4030d
package
com.reactlibrary
;
import
android.content.Context
;
import
com.facebook.react.NativeModuleRegistryBuilder
;
import
com.facebook.react.ReactPackage
;
import
com.facebook.react.bridge.CatalystInstance
;
import
com.facebook.react.bridge.CatalystInstanceImpl
;
import
com.facebook.react.bridge.JSBundleLoader
;
import
com.facebook.react.bridge.JSCJavaScriptExecutor
;
import
com.facebook.react.bridge.JavaScriptExecutor
;
import
com.facebook.react.bridge.NativeModule
;
import
com.facebook.react.bridge.NativeModuleCallExceptionHandler
;
import
com.facebook.react.bridge.ReactApplicationContext
;
import
com.facebook.react.ReactInstanceManager
;
import
com.facebook.react.bridge.WritableNativeMap
;
import
com.facebook.react.bridge.queue.ReactQueueConfigurationSpec
;
import
com.facebook.react.devsupport.interfaces.DevSupportManager
;
import
com.facebook.soloader.SoLoader
;
import
java.util.ArrayList
;
import
java.util.concurrent.Callable
;
public
class
ReactContextBuilder
{
private
Context
parentContext
;
private
JSBundleLoader
jsBundleLoader
;
private
DevSupportManager
devSupportManager
;
private
ReactInstanceManager
instanceManager
;
private
ArrayList
<
ReactPackage
>
reactPackages
;
public
ReactContextBuilder
(
Context
context
)
{
this
.
parentContext
=
context
;
SoLoader
.
init
(
context
,
/* native exopackage */
false
);
}
public
ReactContextBuilder
setJSBundleLoader
(
JSBundleLoader
jsBundleLoader
)
{
this
.
jsBundleLoader
=
jsBundleLoader
;
return
this
;
}
public
ReactContextBuilder
setDevSupportManager
(
DevSupportManager
devSupportManager
)
{
this
.
devSupportManager
=
devSupportManager
;
return
this
;
}
public
ReactContextBuilder
setReactInstanceManager
(
ReactInstanceManager
manager
)
{
this
.
instanceManager
=
manager
;
return
this
;
}
public
ReactContextBuilder
setReactPackages
(
ArrayList
<
ReactPackage
>
reactPackages
)
{
this
.
reactPackages
=
reactPackages
;
return
this
;
}
public
ReactApplicationContext
build
()
throws
Exception
{
JavaScriptExecutor
jsExecutor
=
new
JSCJavaScriptExecutor
.
Factory
(
new
WritableNativeMap
()).
create
();
// fresh new react context
final
ReactApplicationContext
reactContext
=
new
ReactApplicationContext
(
parentContext
);
if
(
devSupportManager
!=
null
)
{
reactContext
.
setNativeModuleCallExceptionHandler
(
devSupportManager
);
}
// load native modules
NativeModuleRegistryBuilder
nativeRegistryBuilder
=
new
NativeModuleRegistryBuilder
(
reactContext
,
this
.
instanceManager
,
false
);
addNativeModules
(
reactContext
,
nativeRegistryBuilder
);
CatalystInstanceImpl
.
Builder
catalystInstanceBuilder
=
new
CatalystInstanceImpl
.
Builder
()
.
setReactQueueConfigurationSpec
(
ReactQueueConfigurationSpec
.
createDefault
())
.
setJSExecutor
(
jsExecutor
)
.
setRegistry
(
nativeRegistryBuilder
.
build
())
.
setJSBundleLoader
(
jsBundleLoader
)
.
setNativeModuleCallExceptionHandler
(
devSupportManager
!=
null
?
devSupportManager
:
createNativeModuleExceptionHandler
()
);
final
CatalystInstance
catalystInstance
;
catalystInstance
=
catalystInstanceBuilder
.
build
();
catalystInstance
.
getReactQueueConfiguration
().
getJSQueueThread
().
callOnQueue
(
new
Callable
<
Object
>()
{
@Override
public
Object
call
()
throws
Exception
{
try
{
reactContext
.
initializeWithInstance
(
catalystInstance
);
catalystInstance
.
runJSBundle
();
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
devSupportManager
.
handleException
(
e
);
}
return
null
;
}
}
).
get
();
catalystInstance
.
getReactQueueConfiguration
().
getUIQueueThread
().
callOnQueue
(
new
Callable
<
Object
>()
{
@Override
public
Object
call
()
throws
Exception
{
try
{
catalystInstance
.
initialize
();
reactContext
.
onHostResume
(
null
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
devSupportManager
.
handleException
(
e
);
}
return
null
;
}
}).
get
();
return
reactContext
;
}
private
NativeModuleCallExceptionHandler
createNativeModuleExceptionHandler
()
{
return
new
NativeModuleCallExceptionHandler
()
{
@Override
public
void
handleException
(
Exception
e
)
{
throw
new
RuntimeException
(
e
);
}
};
}
private
void
addNativeModules
(
ReactApplicationContext
reactContext
,
NativeModuleRegistryBuilder
nativeRegistryBuilder
)
{
for
(
int
i
=
0
;
i
<
reactPackages
.
size
();
i
++)
{
ReactPackage
reactPackage
=
reactPackages
.
get
(
i
);
for
(
NativeModule
nativeModule
:
reactPackage
.
createNativeModules
(
reactContext
))
{
nativeRegistryBuilder
.
addNativeModule
(
nativeModule
);
}
}
}
}
\ No newline at end of file
android/src/main/java/com/reactlibrary/ThreadSelfModule.java
0 → 100644
View file @
ecb4030d
package
com.reactlibrary
;
import
com.facebook.react.bridge.ReactApplicationContext
;
import
com.facebook.react.bridge.ReactContextBaseJavaModule
;
import
com.facebook.react.bridge.ReactMethod
;
import
com.facebook.react.modules.core.DeviceEventManagerModule
;
public
class
ThreadSelfModule
extends
ReactContextBaseJavaModule
{
private
int
threadId
;
private
ReactApplicationContext
parentContext
;
public
ThreadSelfModule
(
ReactApplicationContext
context
)
{
super
(
context
);
}
public
void
initialize
(
int
threadId
,
ReactApplicationContext
parentContext
)
{
this
.
parentContext
=
parentContext
;
this
.
threadId
=
threadId
;
}
@Override
public
String
getName
()
{
return
"ThreadSelfManager"
;
}
@ReactMethod
public
void
postMessage
(
String
data
)
{
if
(
parentContext
==
null
)
{
return
;
}
parentContext
.
getJSModule
(
DeviceEventManagerModule
.
RCTDeviceEventEmitter
.
class
)
.
emit
(
"Thread"
+
String
.
valueOf
(
threadId
),
data
);
}
}
\ No newline at end of file
android/src/main/java/com/reactlibrary/UIManagerStubModule.java
0 → 100644
View file @
ecb4030d
package
com.reactlibrary
;
import
com.facebook.react.bridge.ReactApplicationContext
;
import
com.facebook.react.bridge.ReactContextBaseJavaModule
;
public
class
UIManagerStubModule
extends
ReactContextBaseJavaModule
{
public
UIManagerStubModule
(
ReactApplicationContext
reactContext
)
{
super
(
reactContext
);
}
@Override
public
String
getName
()
{
return
"UIManager"
;
}
}
\ No newline at end of file
example/ThreadExample/android/app/build.gradle
View file @
ecb4030d
...
...
@@ -133,6 +133,7 @@ android {
}
dependencies
{
compile
project
(
':react-native-thread'
)
compile
fileTree
(
dir:
"libs"
,
include:
[
"*.jar"
])
compile
"com.android.support:appcompat-v7:23.0.1"
compile
"com.facebook.react:react-native:+"
// From node_modules
...
...
example/ThreadExample/android/app/src/main/java/com/threadexample/MainApplication.java
View file @
ecb4030d
...
...
@@ -3,6 +3,7 @@ package com.threadexample;
import
android.app.Application
;
import
com.facebook.react.ReactApplication
;
import
com.reactlibrary.RNThreadPackage
;
import
com.facebook.react.ReactNativeHost
;
import
com.facebook.react.ReactPackage
;
import
com.facebook.react.shell.MainReactPackage
;
...
...
@@ -22,7 +23,8 @@ public class MainApplication extends Application implements ReactApplication {
@Override
protected
List
<
ReactPackage
>
getPackages
()
{
return
Arrays
.<
ReactPackage
>
asList
(
new
MainReactPackage
()
new
MainReactPackage
(),
new
RNThreadPackage
(
mReactNativeHost
)
);
}
};
...
...
example/ThreadExample/android/settings.gradle
View file @
ecb4030d
rootProject
.
name
=
'ThreadExample'
include
':react-native-thread'
project
(
':react-native-thread'
).
projectDir
=
new
File
(
rootProject
.
projectDir
,
'../node_modules/react-native-thread/android'
)
include
':app'
example/ThreadExample/index.android.js
View file @
ecb4030d
/**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*/
import
React
,
{
Component
}
from
'
react
'
;
import
{
AppRegistry
,
StyleSheet
,
Text
,
View
View
,
TouchableOpacity
,
}
from
'
react-native
'
;
export
default
class
ThreadExample
extends
Component
{
import
{
Thread
}
from
'
react-native-thread
'
;
class
ThreadExample
extends
Component
{
componentDidMount
()
{
this
.
worker
=
new
Thread
(
'
worker.js
'
);
this
.
worker
.
onmessage
=
(
message
)
=>
{
console
.
log
(
"
Got message from worker
"
,
message
);
}
}
render
()
{
return
(
<
View
style
=
{
styles
.
container
}
>
<
Text
style
=
{
styles
.
welcome
}
>
Welcome
to
React
Native
!
<
/Text
>
<
Text
style
=
{
styles
.
instructions
}
>
To
get
started
,
edit
index
.
android
.
js
<
/Text
>
<
Text
style
=
{
styles
.
instructions
}
>
Double
tap
R
on
your
keyboard
to
reload
,{
'
\n
'
}
Shake
or
press
menu
button
for
dev
menu
<
/Text
>
<
TouchableOpacity
onPress
=
{()
=>
{
console
.
log
(
'
SENDING MESSAGE TO WORKER
'
);
this
.
worker
.
postMessage
(
"
Hello from main thread
"
);
}}
>
<
Text
style
=
{
styles
.
welcome
}
>
Send
message
<
/Text
>
<
/TouchableOpacity
>
<
/View
>
);
}
...
...
@@ -51,3 +55,4 @@ const styles = StyleSheet.create({
});
AppRegistry
.
registerComponent
(
'
ThreadExample
'
,
()
=>
ThreadExample
);
package.json
View file @
ecb4030d
{
"name"
:
"react-native-thread"
,
"version"
:
"1.0.0"
,
...
...
@@ -13,12 +12,13 @@
"author"
:
""
,
"license"
:
""
,
"files"
:
[
"android/"
,
"ios/"
,
"js/"
,
"index.js"
],
"peerDependencies"
:
{
"react-native"
:
"
^
0.41.2"
,
"react-native"
:
"
>=
0.41.2"
,
"react-native-windows"
:
"0.41.0-rc.1"
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment